Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // v0.4.0 שחקן נגד שחקן עם מהלכי שרשרת ועם שרופים ועם התייחסות לתיקו כשיש מלך מול מלך. בלי תיקו כשחוזרים על אותו מהלך 15 פעמים.
- #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,
- Is_it_sharsheret_in_rules_F_was_a_lie, after_sharsheret_move_must_be_again_kill_move, Must_eat_when_possible};
- class a_location{
- public:
- int i;
- int b;
- a_location(){ // המסיים null יוצר ברירת מחדל שהיא כמו ה
- i=0;
- b=0;
- }
- };
- class LocationsArray{
- public:
- a_location array[13]; // null לכל שחקן יש לכל היותר 12 שחקנים. עוד אחד עבור ה
- };
- 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 :מאחסן את פעולת השחקן האנושי. באופן הבא
- // int mode = 0; // מצב המשחק. 0 פירושו אדם נגד אדם. 1 פירושו אדם נגד מחשב. וככל שעולה המספר כך עולה רמת הקושי
- // Color turn_color=White; // התור של מי. בחרנו כאן איזה צבע ראשון
- //////////////////////////////////////////////////////////////// //הצהרות על פונקציות
- bool check_Future_possibility_for_sharsheret(FromTo a_move, Board this_board);
- void move_soldier(FromTo this_move, Board * this_board_P);
- errors rules (FromTo this_move, Board * this_board_P, bool Is_it_sharsheret=false);
- void Print_Damka();
- unsigned int AVBTN(int a, int b);
- int check_direction_on_the_axis(int exit_point, int aim_point);
- ////////////////////////////////////////////////////////////////
- // אולי אפשר למחוק את הפונקציה הזאת:
- bool is_this_soldier_not_stuck(a_location location, Board * this_board_P){ // חייב לקבל חייל או מלך ולא ריק. לא יודע להתמודד עם מהלך שרשרת
- Color this_color = (* this_board_P).DamkaArray[location.i][location.b].Soldier_Color;
- Color enemy_color = (this_color==White)? Black : White;
- if((* this_board_P).DamkaArray[location.i][location.b].king == true || (* this_board_P).DamkaArray[location.i][location.b].AteBefore == true){ // אם זה מלך או אם זה מהלך שרשרת שיכולים ללכת ל4 כיוונים
- if(location.i+1<8 && location.b+1<8){ // ציר ראשון
- if ((* this_board_P).DamkaArray[location.i+1][location.b+1].Soldier_Color==empty) return true;
- if(location.i+2<8 && location.b+2<8){
- if ((* this_board_P).DamkaArray[location.i+2][location.b+2].Soldier_Color==empty && (* this_board_P).DamkaArray[location.i+1][location.b+1].Soldier_Color==enemy_color) return true;
- }
- }
- if(location.i+1<8 && location.b-1>=0){ // ציר שני
- if ((* this_board_P).DamkaArray[location.i+1][location.b-1].Soldier_Color==empty) return true;
- if(location.i+2<8 && location.b-2>=0){
- if ((* this_board_P).DamkaArray[location.i+2][location.b-2].Soldier_Color==empty && (* this_board_P).DamkaArray[location.i+1][location.b-1].Soldier_Color==enemy_color) return true;
- }
- }
- if(location.i-1>=0 && location.b-1>=0){ // ציר שלישי
- if ((* this_board_P).DamkaArray[location.i-1][location.b-1].Soldier_Color==empty) return true;
- if(location.i-2>=0 && location.b-2>=0){
- if ((* this_board_P).DamkaArray[location.i-2][location.b-2].Soldier_Color==empty && (* this_board_P).DamkaArray[location.i-1][location.b-1].Soldier_Color==enemy_color) return true;
- }
- }
- if(location.i-1>=0 && location.b+1<8){ // ציר רביעי
- if ((* this_board_P).DamkaArray[location.i-1][location.b+1].Soldier_Color==empty) return true;
- if(location.i-2>=0 && location.b+2<8){
- if ((* this_board_P).DamkaArray[location.i-2][location.b+2].Soldier_Color==empty && (* this_board_P).DamkaArray[location.i-1][location.b+1].Soldier_Color==enemy_color) return true;
- }
- }
- }
- else{ // אם זה לא מלך
- if (this_color == White){
- if(location.i-1>=0 && location.b-1>=0){
- if ((* this_board_P).DamkaArray[location.i-1][location.b-1].Soldier_Color==empty) return true;
- if(location.i-2>=0 && location.b-2>=0){
- if ((* this_board_P).DamkaArray[location.i-2][location.b-2].Soldier_Color==empty && (* this_board_P).DamkaArray[location.i-1][location.b-1].Soldier_Color==enemy_color) return true;
- }
- }
- if(location.i-1>=0 && location.b+1<8){
- if ((* this_board_P).DamkaArray[location.i-1][location.b+1].Soldier_Color==empty) return true;
- if(location.i-2>=0 && location.b+2<8){
- if ((* this_board_P).DamkaArray[location.i-2][location.b+2].Soldier_Color==empty && (* this_board_P).DamkaArray[location.i-1][location.b+1].Soldier_Color==enemy_color) return true;
- }
- }
- }
- else{
- if(location.i+1<8 && location.b+1<8){
- if ((* this_board_P).DamkaArray[location.i+1][location.b+1].Soldier_Color==empty) return true;
- if(location.i+2<8 && location.b+2<8){
- if ((* this_board_P).DamkaArray[location.i+2][location.b+2].Soldier_Color==empty && (* this_board_P).DamkaArray[location.i+1][location.b+1].Soldier_Color==enemy_color) return true;
- }
- }
- if(location.i+1<8 && location.b-1>=0){
- if ((* this_board_P).DamkaArray[location.i+1][location.b-1].Soldier_Color==empty) return true;
- if(location.i+2<8 && location.b-2>=0){
- if ((* this_board_P).DamkaArray[location.i+2][location.b-2].Soldier_Color==empty && (* this_board_P).DamkaArray[location.i+1][location.b-1].Soldier_Color==enemy_color) return true;
- }
- }
- }
- }
- return false;
- }
- bool is_this_soldier_can_do_a_kiil_move(a_location location, Board * this_board_P){
- // הפונקציה חייבת לקבל כתובת של חייל מאיזה שהוא צבע. הפונקציה עונה האם אפשרי שהוא יאכל עכשיו
- // הפןנקציה לא יודעת שאם חייל נמצא במהלך שרשרת אז הוא יכול לאכול אחורה
- int counter_i, counter_b, i, b;
- 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- אם מהיעד למטרה ערכי ציר ה
- Color enemy_color = ((*this_board_P).DamkaArray[location.i][location.b].Soldier_Color==White)? Black : White ;
- if((*this_board_P).DamkaArray[location.i][location.b].king==true){ // אם הוא מלך אז אין צורך להתחשב בכיוון ובמרחק
- int AV_i;// =AVBTN(i1,i2); // Absolute_value
- int AV_b;// =AVBTN(b1,b2);
- bool flag;
- for (counter_i=0; counter_i<8; counter_i++){
- for (counter_b=0; counter_b<8; counter_b++){
- if((counter_i+counter_b)%2==0) continue; // לא משבצת לבנה
- if(location.i == counter_i || location.b == counter_b) continue; // לא באותה שורה או עמודה
- if((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color != empty) continue; // היעד לא תפוס
- if(AVBTN(location.i,counter_i) != AVBTN(location.b,counter_b)) continue; // אותו אלכסון
- direction_i=check_direction_on_the_axis(location.i,counter_i);
- direction_b=check_direction_on_the_axis(location.b,counter_b);
- flag=true;
- for(i=location.i+direction_i, b=location.b+direction_b; i != counter_i; i+=direction_i, b+=direction_b){ // סריקה על הציר מהמלך ליעד האם יש אין חייל מאותו צבע והאם יש חייל אויב שאפשר לאכול
- if ((*this_board_P).DamkaArray[i][b].Soldier_Color == (*this_board_P).DamkaArray[location.i][location.b].Soldier_Color){
- flag = false;
- break;
- }
- }
- if (flag == false) continue; // בדיקה באמצעות הלולאה האם יש צבע ידיד על הציר
- if ((*this_board_P).DamkaArray[i][b].Soldier_Color == empty)
- if ((*this_board_P).DamkaArray[i-direction_i][b-direction_b].Soldier_Color == enemy_color) // && i-direction_i != location.i // enemy_color אין צורך בבדיקה הזאת שלא יחשוב שהוא אוכל את עצמו - משום שאם זה היה הוא עצמו אז זה לא היה
- return true;
- }
- }
- return false;
- }
- else{
- if ((*this_board_P).DamkaArray[location.i][location.b].AteBefore == true){
- // נבדוק כל פעם כיוון אחד מארבעת הכיוונים האפשריים האם לאותו כיוון אפשר לאכול
- if(location.i+2 < 8 && location.b+2 <8){
- if((*this_board_P).DamkaArray[location.i+2][location.b+2].Soldier_Color == empty){
- if ((*this_board_P).DamkaArray[location.i+1][location.b+1].Soldier_Color == enemy_color) return true;
- }
- }
- if(location.i+2 < 8 && location.b-2 >=0){
- if((*this_board_P).DamkaArray[location.i+2][location.b-2].Soldier_Color == empty){
- if ((*this_board_P).DamkaArray[location.i+1][location.b-1].Soldier_Color == enemy_color) return true;
- }
- }
- if(location.i-2 >=0 && location.b-2 >=0){
- if((*this_board_P).DamkaArray[location.i-2][location.b-2].Soldier_Color == empty){
- if ((*this_board_P).DamkaArray[location.i-1][location.b-1].Soldier_Color == enemy_color) return true;
- }
- }
- if(location.i-2 >0 && location.b+2 <8){
- if((*this_board_P).DamkaArray[location.i-2][location.b+2].Soldier_Color == empty){
- if ((*this_board_P).DamkaArray[location.i-1][location.b+1].Soldier_Color == enemy_color) return true;
- }
- }
- return false;
- }
- else{
- if((*this_board_P).DamkaArray[location.i][location.b].Soldier_Color == White){ // כאן נבדוק אכילה לכיוונים האפשריים של לבן
- if(location.i-2 >=0 && location.b-2 >=0){
- if((*this_board_P).DamkaArray[location.i-2][location.b-2].Soldier_Color == empty){
- if ((*this_board_P).DamkaArray[location.i-1][location.b-1].Soldier_Color == enemy_color) return true;
- }
- }
- if(location.i-2 >0 && location.b+2 <8){
- if((*this_board_P).DamkaArray[location.i-2][location.b+2].Soldier_Color == empty){
- if ((*this_board_P).DamkaArray[location.i-1][location.b+1].Soldier_Color == enemy_color) return true;
- }
- }
- }
- else{ // כאן נבדוק אכילה לכיוונים האפשריים של שחור
- if(location.i+2 < 8 && location.b+2 <8){
- if((*this_board_P).DamkaArray[location.i+2][location.b+2].Soldier_Color == empty){
- if ((*this_board_P).DamkaArray[location.i+1][location.b+1].Soldier_Color == enemy_color) return true;
- }
- }
- if(location.i+2 < 8 && location.b-2 >=0){
- if((*this_board_P).DamkaArray[location.i+2][location.b-2].Soldier_Color == empty){
- if ((*this_board_P).DamkaArray[location.i+1][location.b-1].Soldier_Color == enemy_color) return true;
- }
- }
- }
- return false;
- }
- }
- }
- /*
- LocationsArray locations_on_the_board_that_can_move(Color turn_color, Board * this_board_P){
- //
- //מקבל צבע ומצביע ללוח ובודק איזה חיילים מאותו צבע יכולים לזוז באופן שלא חוסמים אותם
- //ואם זה לא מהלך הריגה אז בודק שאין חייל אחר שיכול להרוג. אם יש חייל אחר שיכול להרוג אז זה לא חוקי כי שרוף
- //מחזיר מערך של מקומות חוקיים
- //
- LocationsArray a;
- int Arr_i;
- int counter_i, counter_b;
- 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){// תנאי ראשון - המקום חייב משבצת שחורה
- if((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color==turn_color){ // תנאי שני - החייל צריך להיות בצבע התור
- }
- }
- }
- }
- return a;
- }
- */
- bool is_this_soldier_can_do_a_legal_move(a_location location, Board * this_board_P){
- int counter_i, counter_b;
- FromTo move;
- move.i1 = location.i;
- move.b1 = location.b;
- for(counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- if((counter_i+counter_b)%2==0 || counter_i==location.i || counter_b==location.b) continue;
- move.i2 = counter_i;
- move.b2 = counter_b;
- if (rules(move, this_board_P, false)==good) return true;
- }
- }
- return false;
- }
- 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; // אופציונלי
- case Is_it_sharsheret_in_rules_F_was_a_lie: { cout<<"Error: This is sharsheret move. Only: "; // הדפסה יפה של השחקן היחיד שאמור להיות מסוגל לעשות שרשרת עכשיו לאחר המהלך הקודם
- int counter_i, counter_b;
- bool find_sharsheret_soldier=false;
- for(counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- if(Real_Damka_soldiers.DamkaArray[counter_i][counter_b].AteBefore==true) {
- find_sharsheret_soldier=true;
- break;
- }
- }
- if (find_sharsheret_soldier==true) break;
- }
- cout<<(char)(counter_b+'A')<<(char)(counter_i+'1')<<" can move (and eat) now.\n";
- break;
- }
- case after_sharsheret_move_must_be_again_kill_move: cout<<"Error: After a sharsheret move must be again a kill move\n"; break;
- case Must_eat_when_possible: cout<<"Error: Must eat when possible\n"; break;
- }
- cout<<"\n\n";
- }
- a_location get_location_from_user_and_convert_to_numbers(char *input, char *FirstOrSecond){
- a_location location_in_numbers;
- while (!((input[0]>='A'&&input[0]<='H' && input[1]>='1'&&input[1]<='8') ||
- (input[0]>='a'&&input[0]<='h' && input[1]>='1'&&input[1]<='8') ||
- (input[1]>='A'&&input[1]<='H' && input[0]>='1'&&input[0]<='8') ||
- (input[1]>='a'&&input[1]<='h' && input[0]>='1'&&input[0]<='8'))){
- cout<<"*Enter a legal "<<FirstOrSecond<<" location: ";
- cin>>input;
- }
- if(input[0]>='A'&&input[0]<='H'){
- location_in_numbers.b=input[0]-'A';
- location_in_numbers.i=input[1]-'1';
- }
- else if(input[0]>='a'&&input[0]<='h'){ // h לפי אסקי אפשר לוותר על הבדיקה של
- location_in_numbers.b=input[0]-'a';
- location_in_numbers.i=input[1]-'1';
- }
- else if(input[1]>='A'&&input[1]<='H'){
- location_in_numbers.b=input[1]-'A';
- location_in_numbers.i=input[0]-'1';
- }
- else{// if(input[1]>='a'&&input[1]<='h') //אין צורך לכתוב // h לפי אסקי אפשר לוותר על הבדיקה של
- location_in_numbers.b=input[1]-'a';
- location_in_numbers.i=input[0]-'1';
- }
- return location_in_numbers;
- }
- FromTo Get_From_User(Color turn_color, bool *Is_it_sharsheret=false){ // מחזיר מהלך שתואם את כל החוקים
- char strFirst[3];
- char strSecond[3];
- FromTo user_move;
- a_location location_A;
- errors ff;
- if (turn_color==White) cout<<"White move!\n"; else cout<<"Black move!\n";
- if(*Is_it_sharsheret == true){ // כל זה כדי שאם זה עכשיו מהלך שרשרת אז נלך ישר לקלט רק של היעד
- int counter_i, counter_b;
- bool find_sharsheret_soldier=false;
- for(counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- if(Real_Damka_soldiers.DamkaArray[counter_i][counter_b].AteBefore==true) {
- find_sharsheret_soldier=true;
- break;
- }
- }
- if (find_sharsheret_soldier==true) break;
- }
- user_move.i1=counter_i;
- user_move.b1=counter_b; // המונה עצר על הראשון - שאמור להיות גם היחיד - שכתוב לו שהוא אכל במהלך האחרון
- do{
- cout<<"Enter second location: ";
- cin>>strSecond;
- location_A = get_location_from_user_and_convert_to_numbers(strSecond, "second");
- user_move.i2 = location_A.i;
- user_move.b2 = location_A.b;
- // עד כאן קלטנו מאיפו ולאן
- ff = rules (user_move, &Real_Damka_soldiers, true);
- print_Error_type(ff);
- }while(ff!=good);
- }
- else{ // אם זה לא מהלך שרשרת
- regret:
- do{
- cout<<"Enter first location: ";
- cin>>strFirst;
- location_A = get_location_from_user_and_convert_to_numbers(strFirst, "first");
- }while (is_this_soldier_can_do_a_legal_move(location_A, &Real_Damka_soldiers)==false ||
- (Real_Damka_soldiers.DamkaArray[location_A.i][location_A.b].Soldier_Color!=turn_color)); // בודק שבמיקום אכן נמצא שחקן מאותו צבע שיכול ללכת בצורה חוקית - כלומר אם זה לא מהלך אכילה אז שאף כלי אחר מאותו צבע לא יוכל לאכול
- user_move.i1 = location_A.i;
- user_move.b1 = location_A.b;
- // עד כאן המקום הראשון הוא בצבע של בעל התור - שזה אומר לא יריב ולא לבן
- while(1){
- cout<<"Enter second location: ";
- cin>>strSecond;
- if(strSecond[0] == 'r' || strSecond[0] == 'R') goto regret;
- location_A = get_location_from_user_and_convert_to_numbers(strSecond, "second");
- user_move.i2 = location_A.i;
- user_move.b2 = location_A.b;
- ff = rules (user_move, &Real_Damka_soldiers, false);
- if(ff==good) break;
- print_Error_type(ff);
- }
- }
- // עד כאן מוצא ויעד תקינים.
- if(check_Future_possibility_for_sharsheret(user_move, Real_Damka_soldiers)==true){
- char sharsheret_check[2];
- do{
- cout<<"Will it be a sharsheret move? (Y/N): ";
- cin>>sharsheret_check;
- }while(sharsheret_check[0]!='n' && sharsheret_check[0]!='N' && sharsheret_check[0]!='y' && sharsheret_check[0]!='Y');
- if(sharsheret_check[0]=='y'|| sharsheret_check[0]=='Y'){
- *Is_it_sharsheret=true;
- }
- else{
- *Is_it_sharsheret=false;
- }
- }
- else *Is_it_sharsheret=false;
- 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<<"\n 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 ABCDEFGH\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+=2){
- 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){
- // תדפיס ארור check_direction_on_the_axis אסור לו לקבל שהמקום הראשון והשני יהיו זהים כי אם כן אז פונקציית
- 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;
- }
- void print_full_damka_details(Board * this_board_P){ // לבדיקות באגים
- int counter_i, counter_b;
- cout<<"\n";
- cout<<"damka colors: \n";
- for(counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- if ((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color==White) cout <<"W";
- if ((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color==Black) cout <<"B";
- if ((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color==empty){if((counter_i+counter_b)%2==1) cout <<(char)176; else cout <<(char)177;}
- }
- cout<<"\n";
- }
- cout<<"\n\n";
- cout<<"damka kings: \n";
- for(counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- if ((*this_board_P).DamkaArray[counter_i][counter_b].king == true) cout <<"m";
- else cout<<(char)178;
- }
- cout<<"\n";
- }
- cout<<"\n\n";
- cout<<"damka Ate before: \n";
- for(counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- if ((*this_board_P).DamkaArray[counter_i][counter_b].AteBefore== true) cout <<"A";
- else cout<<(char)178;
- }
- cout<<"\n";
- }
- cout<<"\n\n";
- }
- bool check_Future_possibility_for_sharsheret(FromTo a_move, Board this_board){ // בודק אם אחרי המהלך, אותו שחקן יוכל להמשיך למהלך שרשרת
- // תחזיר ארור is_it_a_kill_move אסור לו לקבל שהמקום הראשון והשני יהיו זהים כי אם כן אז פונקציית
- 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;
- // cout<<"here rules. exmp.i1: "<<exmp.i1<<" exmp.b1: "<<exmp.b1<<" exmp.i2: "<<exmp.i2<<" exmp.b2: "<<exmp.b2<<"\n";
- if(rules(exmp, &this_board, true)==good){ // שלא חשבתי עליו לעומק true צריך לעקוב אחר ארגומנט ה
- 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){
- // לא תעבוד is_it_a_kill_move אסור לקבל מוצא ויעד זהים כי אם כן
- 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- אם מהיעד למטרה ערכי ציר ה
- if(is_it_a_kill_move(this_move, this_board_P)){
- (*this_board_P).DamkaArray[i1][b1].AteBefore=true; // מזיזים את המוצא ולא את היעד כי הוא תיכף יעבור ליעד
- }
- (*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, bool Is_it_sharsheret){
- /*
- הפונקציה בודקת שהעברה אפשרית, אם כן - מעבירה חיילים ומשיבה הצלחה
- אחרת - משיבה כישלון ומחזירה את סוג הכישלון
- סוגי כישלון:
- המיקומים שקיבלנו הם מחוץ ללוח .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; // בדיקה שהיעד ריק. אגב זה גם בודק שהמקום הראשון והשני לא זהים
- if(i1==i2||b1==b2) return Not_in_the_same_diagonal;
- // :משתנים שיועילו בהמשך
- 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; // בדיקה שזה על אותו אלכסון. נכונה גם עבור מלכים
- bool a_kill_move = is_it_a_kill_move(this_move, this_board_P);
- if (Is_it_sharsheret == true){ // יתכן שלא יהיה צריך את הבדיקה הזאת הראשונה
- if((*this_board_P).DamkaArray[i1][b1].AteBefore == false) return Is_it_sharsheret_in_rules_F_was_a_lie;
- if (a_kill_move==false) return after_sharsheret_move_must_be_again_kill_move ;
- }
- 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; // השורה הזאת לא נכונה. צריך לבדוק למה.
- // צריך לדון בדיוק מה מותר ואסור למלך לעשות כדי לכתוב את זה. // ///// // ///// //
- }
- // מכאן זו בדיקת שרופים
- a_location location;
- location.i = i1;
- location.b = b1;
- if (a_kill_move==false){
- for (counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- if((counter_b+counter_i)%2==0) continue;
- if((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color != this_color) continue;
- location.i = counter_i;
- location.b = counter_b;
- if (is_this_soldier_can_do_a_kiil_move(location, this_board_P) == true) return Must_eat_when_possible;
- }
- }
- }
- return good;
- }
- void Check_for_victory(Board *this_board_P, Color turn_color){
- // אחרי שמסיימים מהלך הפונקציה הזאת מקבלת אא צבע התור של היריב ובודקת אם ניצחנו. אסור להגיע לפונקציה אם עכשיו מהלך רשרת ושוב תורנו במקום תור היריב
- int black_kings = 0, white_kings = 0, black_soldiers = 0, white_soldiers = 0;
- int counter_i, counter_b;
- for(counter_i=0; counter_i<8; counter_i++){ // סריקה כמה חיילים ומלכים יש לכל צד
- for(counter_b=0; counter_b<8; counter_b++){
- if((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color == Black){
- if ((*this_board_P).DamkaArray[counter_i][counter_b].king == true) black_kings++;
- else black_soldiers++;
- }
- if((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color == White){
- if ((*this_board_P).DamkaArray[counter_i][counter_b].king == true) white_kings++;
- else white_soldiers++;
- }
- }
- }
- if (black_kings+black_soldiers==0){
- cout<<"------White won!------\n\n";
- cout<<"White have: "<<white_soldiers<<" soldiers, "<<white_kings<<" kings \n\n";
- getchar();
- exit(0);
- }
- if (white_kings+white_soldiers==0){
- cout<<"------Black won!------\n\n";
- cout<<"Black have: "<<black_soldiers<<" soldiers, "<<black_kings<<" kings\n\n";
- getchar();
- exit(0);
- }
- // אם התור עכשיו הוא של הלבנים - אם הם חסומים אז השחורים ניצחו. וכן להפך
- a_location location;
- bool flag = false;
- for(counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- if ((counter_i+counter_b)%2==0) continue;
- if((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color == turn_color){ // כך זה לא ריק ומאותו הצבע
- location.i = counter_i;
- location.b = counter_b;
- if(is_this_soldier_not_stuck(location, this_board_P)){
- flag = true;
- break;
- }
- }
- }
- if (flag == true) break;
- }
- if (flag == false){ // כלומר אם אין אף חייל בצבע התור שיכול לזוז
- if(turn_color==White) cout<<"White stuck\n------Black won!------\n\n";
- else cout<<"Black stuck\n------White won!------\n\n";
- cout<<"White have: "<<white_soldiers<<" soldiers, "<<white_kings<<" kings \n";
- cout<<"Black have: "<<black_soldiers<<" soldiers, "<<black_kings<<" kings\n\n";
- getchar();
- exit(0);
- }
- // זה מקרה מיוחד של תיקו מלך מול מלך
- if(white_soldiers==0 && black_soldiers==0 && white_kings==1 && black_kings==1){
- // אם שני מלכים נשארו אז זה אמור להיות תיקו. בתנאי שהמלך שעכשיו תורו לא יכול לאכול את המלך השני
- a_location black_king_location, white_king_location;
- for(counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- if((counter_i+counter_b)%2==0) continue;
- if ((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color == White){
- white_king_location.i = counter_i;
- white_king_location.b = counter_b;
- }
- if ((*this_board_P).DamkaArray[counter_i][counter_b].Soldier_Color == Black){
- black_king_location.i = counter_i;
- black_king_location.b = counter_b;
- }
- }
- } // עד כאן אנחנו יודעים את מיקום המלכים
- flag = false;
- FromTo move_exm;
- Board board_exm;
- if(turn_color == White){
- if(is_this_soldier_can_do_a_kiil_move(white_king_location, this_board_P) == false){
- // // קיים תנאי נוסף: אם לא משנה מה המלך שעכשיו תורו יעשה - הוא תמיד יאכל מייד על ידי המלך השני - אז הוא הפסיד
- move_exm.i1 = white_king_location.i;
- move_exm.b1 = white_king_location.b;
- for(counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- move_exm.i2 = counter_i;
- move_exm.b2 = counter_b;
- if(rules(move_exm,this_board_P,false)!=good) continue;
- board_exm=(*this_board_P);
- move_soldier(move_exm, &board_exm);
- if(is_this_soldier_can_do_a_kiil_move(black_king_location, &board_exm)==false){
- flag = true; // כי זה תיקו משום שלא כל מהלך שהוא יעשה הוא יאכל
- break;
- }
- }
- if(flag==true) break;
- }
- }
- }
- else{ // אם צבע התור זה שחור
- if(is_this_soldier_can_do_a_kiil_move(black_king_location, this_board_P) == false){
- // // קיים תנאי נוסף: אם לא משנה מה המלך שעכשיו תורו יעשה - הוא תמיד יאכל מייד על ידי המלך השני - אז הוא הפסיד
- move_exm.i1 = black_king_location.i;
- move_exm.b1 = black_king_location.b;
- for(counter_i=0; counter_i<8; counter_i++){
- for(counter_b=0; counter_b<8; counter_b++){
- move_exm.i2 = counter_i;
- move_exm.b2 = counter_b;
- if(rules(move_exm,this_board_P,false)!=good) continue;
- board_exm=(*this_board_P);
- move_soldier(move_exm, &board_exm);
- if(is_this_soldier_can_do_a_kiil_move(white_king_location, &board_exm)==false){
- flag = true; // כי זה תיקו משום שלא כל מהלך שהוא יעשה הוא יאכל
- break;
- }
- }
- if(flag==true) break;
- }
- }
- }
- if(flag == true){
- cout<<"------2 kings! it's a tie!------\n\n";
- getchar();
- exit(0);
- }
- }
- }
- void main(){
- char c = '"';
- cout<<"(C) Created by a student NN 04/05/2017\n\nThis is v0.4.0 Damka game ("<<c<<"checkers"<<c<<") for 2 people.\nI hope you know the rules...\nOne more rule: king must stop immediately after the soldier he ate.\nIf you want to change your first selection, press R\n\n\n";
- FromTo ff;
- // חוקים וקרדיט והסבר על איך מתחרטים
- Order_First_Damka();
- bool Is_it_sharsheret = false;
- Print_Damka();
- do{
- do{ // מהלך של הלבנים
- ff= Get_From_User(White, &Is_it_sharsheret);
- move_soldier(ff, &Real_Damka_soldiers);
- Print_Damka();
- if (Is_it_sharsheret == false) Check_for_victory(&Real_Damka_soldiers, Black);
- }while(Is_it_sharsheret);
- Real_Damka_soldiers.DamkaArray[ff.i2][ff.b2].AteBefore=false; // עבור מהלכי שרשרת שנגמרו - וגם סתם מהלכים רגילים
- Is_it_sharsheret=false;
- do{ // מהלך של השחורים
- ff= Get_From_User(Black, &Is_it_sharsheret);
- move_soldier(ff, &Real_Damka_soldiers);
- Print_Damka();
- if (Is_it_sharsheret == false) Check_for_victory(&Real_Damka_soldiers, White);
- }while(Is_it_sharsheret);
- Real_Damka_soldiers.DamkaArray[ff.i2][ff.b2].AteBefore=false; // עבור מהלכי שרשרת שנגמרו - וגם סתם מהלכים רגילים
- Is_it_sharsheret=false;
- }while(1);
- }// צריך בדיקה שלא להכנס למצב אין סופי שצד אחד לא יכול לזוז - לדלג על התור שלו. ואם שניהם לא יכולים לזוז אז להכריז על תיקו
- // באג: אם אןמרים שהיה מהלך שרשרת - הוא לא יודע לאפיין שרק החייל שקודם זז יכול שוב לזוז, ולא אחרים
- // להוסיף שרופים
- // להוסיף שאסור לחזור על אותו מהלך יותר מ3 פעמים
- //
Advertisement
Add Comment
Please, Sign In to add comment