Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- using namespace std;
- enum Color {empty, Black, White}; // לבנים למטה
- enum errors {good, bad_arguments, first_location_empty, second_location_not_empty, bad_direction,
- Not_in_the_same_diagonal, second_location_is_a_white_square, opponent_tries_to_eat_himself,
- Skipping, error_in_check_direction_on_the_axis_F, king_tries_to_eat_2_or_more, king_did_not_stop_immediately_after_soldier};
- class Square{ //משבצת
- public:
- Color Soldier_Color;
- bool king;
- bool AteBefore;
- Square(Color CC = empty, bool aa = false, bool KK = false){
- Soldier_Color = CC;
- AteBefore = aa;
- king = KK;
- }
- };
- class Board{
- public:
- Square DamkaArray [8][8];
- };
- Board Real_Damka_soldiers; // המערך הראשי
- class FromTo{
- public:
- int i1,i2,b1,b2;
- };
- // int user_move[4]; // עמודה b מייצגת מספר שורה ו i הם יעד. האות i2,b2 הם מוצא. ו i1,b1 כאשר i1,b1,i2,b2 :מאחסן את פעולת השחקן האנושי. באופן הבא
- bool Is_it_sharsheret;
- // int mode = 0; // מצב המשחק. 0 פירושו אדם נגד אדם. 1 פירושו אדם נגד מחשב. וככל שעולה המספר כך עולה רמת הקושי
- // Color turn_color=White; // התור של מי. בחרנו כאן איזה צבע ראשון
- void print_Error_type(errors en){
- if (en==good) return;
- cout<< "\n**Error found:\n";
- switch(en) {
- case bad_arguments: cout<<"Error: bad arguments\n"; break;
- case first_location_empty: cout<<"Error: first location empty\n"; break;
- case second_location_not_empty: cout<<"Error: second location not empty\n"; break;
- case bad_direction: cout<<"Error: bad direction\n"; break;
- case Not_in_the_same_diagonal: cout<<"Error: Not_in_the_same_diagonal\n"; break;
- case second_location_is_a_white_square: cout<<"Error: second location is a white square\n"; break;
- case opponent_tries_to_eat_himself:cout<<"Error: opponent tries to eat himself\n"; break;
- case Skipping: cout<<"Error: Skipping\n"; break;
- case error_in_check_direction_on_the_axis_F: cout<<"Error: error_in_check_direction_on_the_axis_F\n"; break;
- case king_tries_to_eat_2_or_more: cout<<"Error: king tries to eat 2 or more\n"; break;
- case king_did_not_stop_immediately_after_soldier: cout<<"Error: king did not stop immediately after a soldier\n"; break; // אופציונלי
- }
- cout<<"\n\n";
- }
- FromTo Get_From_User(Color turn_color){ // מחזיר מהלך שתואם את כל החוקים
- char strFirst[3];
- char strSecond[3];
- char sharsheret_check;
- FromTo user_move; // בשביל הערך המספרי שמומר מהאותיות
- do{
- do{
- if (turn_color==White) {cout<<"White move!\nEnter first location: ";}
- else {cout<<"Black move!\nEnter first location: ";}
- cin>>strFirst;
- while(1){
- while (!((strFirst[0]>='A'&&strFirst[0]<='H' && strFirst[1]>='1'&&strFirst[1]<='8') ||
- (strFirst[0]>='a'&&strFirst[0]<='h' && strFirst[1]>='1'&&strFirst[1]<='8') ||
- (strFirst[1]>='A'&&strFirst[1]<='H' && strFirst[0]>='1'&&strFirst[0]<='8') ||
- (strFirst[1]>='a'&&strFirst[1]<='h' && strFirst[0]>='1'&&strFirst[0]<='8'))){
- cout<<"*Enter a legal first location: ";
- cin>>strFirst;
- }
- // עד כאן קליטה למשתני עזר
- if(strFirst[0]>='A'&&strFirst[0]<='H'){
- user_move.b1=strFirst[0]-'A';
- user_move.i1=strFirst[1]-'1';
- }
- else if(strFirst[0]>='a'&&strFirst[0]<='h'){ // h לפי אסקי אפשר לוותר על הבדיקה של
- user_move.b1=strFirst[0]-'a';
- user_move.i1=strFirst[1]-'1';
- }
- else if(strFirst[1]>='A'&&strFirst[1]<='H'){
- user_move.b1=strFirst[1]-'A';
- user_move.i1=strFirst[0]-'1';
- }
- else{// if(strFirst[1]>='a'&&strFirst[1]<='h') //אין צורך לכתוב // h לפי אסקי אפשר לוותר על הבדיקה של
- user_move.b1=strFirst[1]-'a';
- user_move.i1=strFirst[0]-'1';
- }
- // עד כאן השמה של משתנה עזר ראשון במערך הגלובלי
- if (Real_Damka_soldiers.DamkaArray[user_move.i1][user_move.b1].Soldier_Color==turn_color){ // בודק שהצבע מתאים לתור -מסתמכים על זה בהמשך. וגם בודק שלא ריק
- break;
- }
- else{
- cout<<"*Please enter black Square in YOUR COLOR: ";
- cin>>strFirst;
- }
- }
- // עד כאן קליטת מוצא
- cout<<"Enter second location: ";
- cin>>strSecond;
- while(1){
- while (!((strSecond[0]>='A'&&strSecond[0]<='H' && strSecond[1]>='1'&&strSecond[1]<='8') ||
- (strSecond[0]>='a'&&strSecond[0]<='h' && strSecond[1]>='1'&&strSecond[1]<='8') ||
- (strSecond[1]>='A'&&strSecond[1]<='H' && strSecond[0]>='1'&&strSecond[0]<='8') ||
- (strSecond[1]>='a'&&strSecond[1]<='h' && strSecond[0]>='1'&&strSecond[0]<='8'))){
- cout<<"*Enter a legal second location: ";
- cin>>strSecond;
- }
- // עד כאן קליטה למשתני עזר של המקום השני
- if(strSecond[0]>='A'&&strSecond[0]<='H'){
- user_move.b2=strSecond[0]-'A';
- user_move.i2=strSecond[1]-'1';
- }
- else if(strSecond[0]>='a'&&strSecond[0]<='h'){ // h לפי אסקי אפשר לוותר על הבדיקה של
- user_move.b2=strSecond[0]-'a';
- user_move.i2=strSecond[1]-'1';
- }
- else if(strSecond[1]>='A'&&strSecond[1]<='H'){
- user_move.b2=strSecond[1]-'A';
- user_move.i2=strSecond[0]-'1';
- }
- else{// if(strSecond[1]>='a'&&strSecond[1]<='h') //אין צורך לכתוב // h לפי אסקי אפשר לוותר על הבדיקה של
- user_move.b2=strSecond[1]-'a';
- user_move.i2=strSecond[0]-'1';
- }
- Color enemy_color = (turn_color==White)? Black : White ;
- if (Real_Damka_soldiers.DamkaArray[user_move.i2][user_move.b2].Soldier_Color==empty && (user_move.i2 + user_move.b2)%2==1 ){ // בודק שהצבע מתאים לתור -מסתמכים על זה בהמשך. וגם בודק שלא ריק
- break;
- }
- else{
- cout<<"*Please enter empty black Square: ";
- cin>>strSecond;
- }
- }
- errors ff = rules (user_move, &Real_Damka_soldiers);
- if (ff==good){
- break;
- }
- else{
- print_Error_type(ff);
- cout<< "\nSo please read the rules...\n";
- }
- }while(1); // לולאה עבור בדיקת המוצא ויעד כחוקיים
- cout<<"Will it be a sharsheret move? (Y/N): ";
- cin>>sharsheret_check;
- while(sharsheret_check!='n' && sharsheret_check!='N' && sharsheret_check!='y' && sharsheret_check!='Y'){
- cout<<"*Only Y/N: ";
- cin>>sharsheret_check;
- }
- if(sharsheret_check=='y'|| sharsheret_check=='Y'){
- if(check_Future_possibility_for_sharsheret(user_move, Real_Damka_soldiers)==true){
- Is_it_sharsheret=true;
- break;
- }
- else{
- cout<<"*This move can't be a sharsheret move!\n*Please try again...\n";
- }
- }
- else{
- Is_it_sharsheret=false;
- break;
- }
- }while(1);// לולאה עבור בדיקת השרשרת כתקינה
- return user_move;
- }
- char convert_to_symbol(int i, int b){ // מקבל מקום במערך הדמקה ומחזיר סמל
- if(Real_Damka_soldiers.DamkaArray[i][b].Soldier_Color == White){
- if(Real_Damka_soldiers.DamkaArray[i][b].king==false) return 'W';
- else return (char)233; // מלך
- }
- if(Real_Damka_soldiers.DamkaArray[i][b].Soldier_Color == Black){
- if(Real_Damka_soldiers.DamkaArray[i][b].king==false) return 'B';
- else return 232;
- }
- else {
- if((i+b)%2==1) return 176; // ה 176 זה הצבע של השחור
- else return 177;
- }
- }
- void Print_Damka(){
- int i,a,b;
- cout<<" ABCDEFGH";
- for(i=0; i<8; i++){
- for(b=0;b<8;b++){
- if(b%8==0) cout<<"\n";
- if(b==0)cout<<i+1<<" "; //מיספור
- cout<<convert_to_symbol(i,b);
- }
- }
- cout<<"\n\n";
- }
- void Order_First_Damka(){
- int i,a,b;
- for(i=0; i<3; i++){
- for(b=0;b<8;b++){
- if ((i+b)%2==1){
- Real_Damka_soldiers.DamkaArray[i][b].Soldier_Color=Black;
- }
- }
- }
- for(i=5; i<8; i++){
- for(b=0;b<8;b++){
- if ((i+b)%2==1){
- Real_Damka_soldiers.DamkaArray[i][b].Soldier_Color=White;
- }
- }
- // עבור בדיקת המלכים
- for(b=0; b<8; b++){
- Real_Damka_soldiers.DamkaArray[5][b].king=true;
- }
- }
- }
- unsigned int AVBTN(int a, int b){ // Absolute_value_between_two_numbers // ערך מוחלט
- if(a>b) return a-b;
- else return b-a;
- }
- void Clear_soldier(int i, int b, Board * this_board_P){
- (*this_board_P).DamkaArray[i][b].king = false;
- // (*this_board_P).DamkaArray[i][b].AteBefore = false; // זה כנראה יהיה מיותר
- (*this_board_P).DamkaArray[i][b].Soldier_Color = empty;
- }
- Color check_soldier_color_between_two_location(int i1, int b1, int i2, int b2, Board * this_board_P){ // שימו לב שצריכה להיות בדיוק משבצת אחת ביניהם // פונקציה לא שימושית. הכנסתי כבר בתוך פונקציית העברה
- return (*this_board_P).DamkaArray[(i1+i2)/2][(b1+b2)/2].Soldier_Color;
- }
- int check_direction_on_the_axis(int exit_point, int aim_point){ // עולים או יורדים i/b בדיקת כיוון על הציר, האם מהיעד למטרה הפרמטרים של ציר
- if (aim_point - exit_point>0) return 1; // עולים
- if (aim_point - exit_point<0) return -1; // יורדים
- print_Error_type(error_in_check_direction_on_the_axis_F); // עבור אם הם באותו מקום
- return error_in_check_direction_on_the_axis_F ;
- }
- bool is_it_a_kill_move(FromTo a_move, Board * this_board_P){
- bool a_kill=false;
- Color this_color = (*this_board_P).DamkaArray[a_move.i1][a_move.b1].Soldier_Color;
- Color enemy_color = (this_color==White)? Black : White ;
- int direction_i=check_direction_on_the_axis(a_move.i1,a_move.i2); // יורדים. אם עולים יהיה 1 i יהיה 1- אם מהיעד למטרה ערכי ציר ה
- int direction_b=check_direction_on_the_axis(a_move.b1,a_move.b2); // יורדים. אם עולים יהיה 1 b יהיה 1- אם מהיעד למטרה ערכי ציר ה
- int counter_i, counter_b;
- for(counter_i=a_move.i1+direction_i, counter_b=a_move.b1+direction_b; counter_i != a_move.i2; counter_i+=direction_i, counter_b+=direction_b){
- if((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color==enemy_color) {
- a_kill=true;
- break;
- }
- }
- return a_kill;
- }
- bool check_Future_possibility_for_sharsheret(FromTo a_move, Board this_board){ // בודק אם אחרי המהלך, אותו שחקן יוכל להמשיך למהלך שרשרת
- if (is_it_a_kill_move(a_move, &this_board)){
- move_soldier(a_move, &this_board);
- int direction_i=check_direction_on_the_axis(a_move.i1,a_move.i2); // יורדים. אם עולים יהיה 1 i יהיה 1- אם מהיעד למטרה ערכי ציר ה
- int direction_b=check_direction_on_the_axis(a_move.b1,a_move.b2); // יורדים. אם עולים יהיה 1 b יהיה 1- אם מהיעד למטרה ערכי ציר ה
- int counter_i, counter_b;
- FromTo exmp;
- exmp.i1 = a_move.i2;
- exmp.b1 = a_move.b2;
- for(counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- if ((counter_i + counter_b)%2==1){
- exmp.i2=counter_i;
- exmp.b2=counter_b;
- if(rules(exmp, &this_board)==good){
- if (is_it_a_kill_move(exmp, &this_board)==true){
- return true;
- }
- }
- else continue;
- }
- else continue;
- }
- }
- }
- else return false;
- }
- void move_soldier(FromTo this_move, Board * this_board_P){
- int i1 = this_move.i1;
- int i2 = this_move.i2;
- int b1 = this_move.b1;
- int b2 = this_move.b2;
- int direction_i=check_direction_on_the_axis(i1,i2); // יורדים. אם עולים יהיה 1 i יהיה 1- אם מהיעד למטרה ערכי ציר ה
- int direction_b=check_direction_on_the_axis(b1,b2); // יורדים. אם עולים יהיה 1 b יהיה 1- אם מהיעד למטרה ערכי ציר ה
- (*this_board_P).DamkaArray[i2][b2] = (*this_board_P).DamkaArray[i1][b1];
- Clear_soldier(i1, b1, this_board_P);
- Clear_soldier(i2 - direction_i, b2 - direction_b, this_board_P); // אכילה. אם ההזזה הזו היא לא אכילה זה לא פגע בכלום
- if((i2==7&& (*this_board_P).DamkaArray[i2][b2].Soldier_Color== Black)||(i2==0 && (*this_board_P).DamkaArray[i2][b2].Soldier_Color== White))
- (*this_board_P).DamkaArray[i2][b2].king=true; // הפיכה למלך
- /*
- if(turn_color == White && sharsheret ==false) {turn_color=Black;} // אחרי בדיקה שזה לא מהלך שרשרת, משנים צבע תור
- else if(turn_color == Black && sharsheret ==false) turn_color=White;
- */
- // צריך לשלוח מכאן לפונקציה שמטפלת במהלך שרשרת, בקליטה שלו, ובהודעות השגיעה // // //
- // צריך להוסיף הגבלה של אכילה חובה- שרוף. אבל צריך לבדוק את החוקים קודם // // //
- // צריך כאן פונקציה להיסטוריה // // //
- }
- errors rules (FromTo this_move, Board * this_board_P){
- /*
- הפונקציה בודקת שהעברה אפשרית, אם כן - מעבירה חיילים ומשיבה הצלחה
- אחרת - משיבה כישלון ומחזירה את סוג הכישלון
- סוגי כישלון:
- המיקומים שקיבלנו הם מחוץ ללוח .1
- 2. הייעד כבר תפוס, או שהמוצא ריק
- 3. היעד הוא משבצת לבנה
- 4. המוצא והיעד לא על אותו אלכסון
- 5. חייל (לא מלך) לבן יורד, או חייל שחור עולה. למעט מהלך שרשרת
- 6. :בחייל (לא מלך) עליו לדלג רק משבצת אלכסונית אחת. ואם הוא אוכל אז רק שתיים, ואז עלינו לבדוק שהאכילה תקינה
- .יש בין המוצא ליעד חייל. והוא לא מאותו צבע
- הגעתי עד כאן
- 7. :אם זה מלך אז הוא יכול ללכת כל מספר שורות (שהוכח כבר שהן בתוך המשחק) אבל בתנאי
- .אין חיילים מאותו צבע בדרך
- .אין יותר מחייל עוין אחד
- .אופציונלי: עליו לעצור מייד אחרי חייל עויין בלי להתרחק ממנו
- */
- /* לא צריך לבדוק את צבע כלי המוצא אם הוא תואם את צבע התור, כי זה כבר נקלט בפונקציית הקלט. שימו לב שהרבה מהפעולות כאן על צבעים היה אפשר לחסוך
- באמצעות המשתנה הגלובלי של צבע התור
- */
- int i1 = this_move.i1;
- int i2 = this_move.i2;
- int b1 = this_move.b1;
- int b2 = this_move.b2;
- Color this_color = (*this_board_P).DamkaArray[i1][b1].Soldier_Color;
- Color second_square = (*this_board_P).DamkaArray[i2][b2].Soldier_Color;
- if(i1>7||i1<0||b1>7||b1<0||i2>7||i2<0||b2>7||b2<0) return bad_arguments; // הכלים במקום שלא קיים // ייתכן שנמנע בקלט מהרקורסיה והמשתמש אפשרות שזה לא יהיה נכון, ואז אפשר לחסוך את הבדיקה הזאת
- if(this_color == empty) return first_location_empty; // אגב זה בודק שהמקום הראשון לא לבן// ייתכן שנמנע בקלט מהרקורסיה אפשרות שזה לא יהיה נכון, ואז אפשר לחסוך את הבדיקה הזאת
- if((i2+b2)%2 == 0) return second_location_is_a_white_square; // יש צורך לבדוק רק את המיקום השני, כי הראשון כבר יודעים שיש בו שחקן
- if(second_square != empty) return second_location_not_empty; // בדיקה שהיעד ריק. אגב זה גם בודק שהמקום הראשון והשני לא זהים
- // :משתנים שיועילו בהמשך
- int AV_i=AVBTN(i1,i2); // שמירת ההפרשים המוחלטים מועילה להמשך // Absolute_value
- int AV_b=AVBTN(b1,b2);
- int direction_i=check_direction_on_the_axis(i1,i2); // יורדים. אם עולים יהיה 1 i יהיה 1- אם מהיעד למטרה ערכי ציר ה
- int direction_b=check_direction_on_the_axis(b1,b2); // יורדים. אם עולים יהיה 1 b יהיה 1- אם מהיעד למטרה ערכי ציר ה
- int counter_i, counter_b;
- if(AV_i!=AV_b) return Not_in_the_same_diagonal; // בדיקה שזה על אותו אלכסון. נכונה גם עבור מלכים
- if((*this_board_P).DamkaArray[i1][b1].king == false){ // חייל ולא מלך
- if ((this_color == White && i1<=i2 && (*this_board_P).DamkaArray[i1][b1].AteBefore == false)|| // אם זה שרשרת אז זה חוקי
- (this_color == Black && i1>=i2 && (*this_board_P).DamkaArray[i1][b1].AteBefore == false))
- return bad_direction; // כיוון לא נכון של שחקן שהלך לכיוון שלו
- if(AV_i>2) return Skipping; // כמובן שגם יותר משתי משבצות זה תמיד דילוג עבור חייל רגיל
- if(AV_i==2){ // נבדוק אם יש ביניהם חייל מאותו צד ואז זו פגיעה עצמית, או אם אין כלל חייל ואז זה דילוג
- Color soldier_color_between_two_location = (*this_board_P).DamkaArray[(i1+i2)/2][(b1+b2)/2].Soldier_Color; // משתנה לחיסכון בפעולות
- if(soldier_color_between_two_location==empty) return Skipping;
- if(this_color == soldier_color_between_two_location){ // בדיקה מה יש ביניהם. נכונה רק עבור הפרש של משפצת אחת בינהם. מה שנכון עבור חייל
- return opponent_tries_to_eat_himself;
- }
- }
- }
- else{ // אם זה מלך
- int Counting_soldiers_eaten=0;
- Color enemy_color = (this_color==White)? Black : White ;
- for(counter_i=i1+direction_i, counter_b=b1+direction_b; counter_i != i2; counter_i+=direction_i, counter_b+=direction_b){
- if((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color==this_color) return opponent_tries_to_eat_himself;
- if((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color!=enemy_color){
- Counting_soldiers_eaten++;
- if (Counting_soldiers_eaten>1) return king_tries_to_eat_2_or_more;
- }
- }
- if((*this_board_P).DamkaArray[i2-direction_i][b2-direction_b].Soldier_Color == empty && Counting_soldiers_eaten==1) return king_did_not_stop_immediately_after_soldier; // השורה הזאת לא נכונה. צריך לבדוק למה.
- // צריך לדון בדיוק מה מותר ואסור למלך לעשות כדי לכתוב את זה. // ///// // ///// //
- }
- }
- int How_many_blacks_left(){
- int i,b,black_Counter=0;
- for(i=0; i<8; i++){
- for(b=0;b<8;b++){
- if (Real_Damka_soldiers.DamkaArray[i][b].Soldier_Color==Black) black_Counter++;
- }
- }
- return black_Counter;
- }
- int How_many_white_left(){
- int i,b,white_Counter=0;
- for(i=0; i<8; i++){
- for(b=0;b<8;b++){
- if (Real_Damka_soldiers.DamkaArray[i][b].Soldier_Color==White) white_Counter++;
- }
- }
- return white_Counter;
- }
- void Check_for_victory(){
- if (How_many_blacks_left()==0){
- cout<<"------White won!------\n\n";
- getchar();
- exit;
- }
- if (How_many_white_left()==0){
- cout<<"------Black won!------\n\n";
- getchar();
- exit;
- }
- // צריך להוסיף יחס שחקנים מלכים ותורות לניצחון
- }
- void main(){
- FromTo ff;
- // bool sharsheret_move;
- Order_First_Damka();
- do{
- Print_Damka();
- do{ // מהלך של הלבנים
- Is_it_sharsheret=false;
- ff= Get_From_User(White);
- move_soldier(ff, &Real_Damka_soldiers);
- Print_Damka();
- Check_for_victory();
- }while(Is_it_sharsheret);
- do{ // מהלך של השחורים
- Is_it_sharsheret=false;
- ff= Get_From_User(Black);
- move_soldier(ff, &Real_Damka_soldiers);
- Print_Damka();
- Check_for_victory();
- }while(Is_it_sharsheret);
- }while(1);
- }// צריך בדיקה שלא להכנס למצב אין סופי שצד אחד לא יכול לזוז - לדלג על התור שלו. ואם שניהם לא יכולים לזוז אז להכריז על תיקו
Advertisement
Add Comment
Please, Sign In to add comment