Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // V0.40 // ארבע בשורה אדם נגד מחשב
- #include <iostream>
- #include <windows.h>
- #include <ctime> // עבור מספר רנדומלי
- // #define Difficulty 5
- using namespace std;
- int Difficulty;
- // מדריך צבעים https://www.youtube.com/watch?v=IXtm7cI21vM
- void setcolor(unsigned short color){
- HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleTextAttribute(hcon, color);
- }
- enum status{empty, white, black};
- enum status main_board [7][6]; /// i,j // הוא 0 j השורה הכי עליונה היא השורה בה
- void reset_board(enum status board [7][6]){
- for(int i=0; i<7; i++){
- for(int j=0; j<6; j++){
- board[i][j] = empty;
- }
- }
- }
- enum status get_Color_at_the_top_position(enum status board [7][6], int loc){ // show פונקצית עזר ל
- for(int j=0; j<6; j++){
- if(board[loc][j] == empty) continue;
- return board[loc][j];
- }
- cout<<"error in get_Color_at_the_top_position\n";
- return empty; // שורה מיותר ליתר ביטחון אם מקבלים עמודה ריקה
- }
- void show(enum status board [7][6], int lastLoc = -1){
- cout<<"\n\n";
- if(lastLoc==-1) cout<<"1 2 3 4 5 6 7";
- else{ // כל זה על מנת להציד איפה הניח התור הקודם
- enum status lastStat = get_Color_at_the_top_position(board, lastLoc);
- for(int i=0; i<7; i++) {
- if(i!=lastLoc) cout<<i+1<<" ";
- else{
- if(lastStat == white){
- setcolor(11);
- cout<<i+1<<" ";
- setcolor(7);
- }
- else{
- setcolor(12);
- cout<<i+1<<" ";
- setcolor(7);
- }
- }
- }
- }
- cout<<"\n_____________\n";
- for(int j=0; j<6; j++){
- for(int i=0; i<7; i++){
- if(board[i][j]== empty) cout<<"O ";
- else if (board[i][j]== white) {
- setcolor(11);
- cout<<"O "; // w
- setcolor(7);
- }
- else {
- setcolor(12);
- cout<<"O "; // b
- setcolor(7);
- }
- }
- cout<<"\n";
- }
- cout<<"\n";
- }
- int get_from_player(enum status stat){
- if (stat==white) cout<<"-White move.\n";
- else cout<<"-Black move.\n";
- int location;
- cout <<"Enter location: ";
- cin>> location;
- while(location<1 || location>7 || main_board[location-1][0] != empty){
- cout<<"Please enter a legal location: ";
- cin >> location;
- }
- cout<<"\n";
- return location-1;
- }
- void Put_in_a_move(enum status board [7][6], int location, enum status stat){
- for(int j=5; j>=0; j--){
- if (board[location][j] == empty){
- board[location][j] = stat;
- break;
- }
- }
- }
- enum status Victory_check (enum status board [7][6]){
- for(int j=5; j>=0; j--){
- for(int i=0; i<4; i++){
- if (board[i][j]==empty) continue;
- for(int b=i+1, q=0; q<3; q++, b++){
- if (board[i][j]!=board[b][j]) break;
- if(q==2) return board[i][j];
- }
- }
- }
- // עד כאן בדיקת ניצחונות אופקיים
- for(int i=0; i<7; i++){
- for(int j=5; j>2; j--){
- if (board[i][j]==empty) continue;
- for(int b=j-1, q=0; q<3; q++, b--){
- if (board[i][j]!=board[i][b]) break;
- if(q==2) return board[i][j];
- }
- }
- }
- // עד כאן בדיקת ניצחונות ישרים
- for(int j=5; j>2; j--){
- for(int i=0; i<4; i++){
- if (board[i][j]==empty) continue;
- for(int q=1; q<4; q++){
- if (board[i][j]!=board[i+q][j-q]) break;
- if(q==3) return board[i][j];
- }
- }
- }
- // עד כאן אלכסון משמאל נמוך לימין גבוה
- for(int j=5; j>2; j--){
- for(int i=3; i<7; i++){
- if (board[i][j]==empty) continue;
- for(int q=1; q<4; q++){
- if (board[i][j]!=board[i-q][j-q]) break;
- if(q==3) return board[i][j];
- }
- }
- }
- // עד כאן אלכסון מימין נמוך לשמאל גבוה
- return empty;
- }
- /* מכאן פונקציות לאדם נגד מחשב */
- void clear_location(enum status board [7][6], int loc){
- for(int j=0; j<6; j++){
- if (board[loc][j] != empty){
- board[loc][j] = empty;
- break;
- }
- }
- }
- int get_first_empty_location_with_bad_array(enum status board [7][6], int arr[7]){
- for(int i=0; i<7; i++){
- if(board[i][0]!=empty || arr[i] == -1)continue;
- return i;
- }
- cout<<"Error in get_first_empty_location_with_bad_array\n";
- }
- int get_first_empty_location(enum status board [7][6]){
- for(int i=0; i<7; i++){
- if(board[i][0]!=empty)continue;
- return i;
- }
- cout<<"Error in get_first_empty_location\n";
- return -1;
- }
- int get_random_location(enum status board [7][6], int arr[7] = NULL){
- int x;
- int fan = 0;
- if(arr==NULL){
- while(1){
- x = rand() % 11;
- if(x==10)x=3;
- else if(x>6) x-=5;
- if(board[x][0]!=empty) continue;
- return x;
- }
- }
- else{
- while(1){
- fan++;
- if (fan==2000) {
- cout<<"ERROR2\nARRAY BAD:\n";
- for(int i=0; i<7; i++){
- if(arr[i]==-1)cout<<i<<". ";
- }cout<<"\n";
- show(board);
- }
- x = rand() % 11;
- if(x==10)x=3;
- else if(x>6) x-=5;
- if(arr[x]==-1) continue;
- if(board[x][0]!=empty)continue;
- return x;
- }
- }
- }
- int check_for_winning_location(enum status board [7][6], enum status stat){
- enum status VictoryFlag = empty;
- for(int i=0; i<7; i++){
- if(board[i][0] != empty) continue;
- Put_in_a_move(board, i, stat);
- VictoryFlag = Victory_check(board);
- clear_location(board, i); // מחזירים את הלוח לאיך שהוא היה לפני השינוי
- if(VictoryFlag == stat) return i;
- }
- return -1; // המשמעות היא שאין מיקום שיניב ניצחון לצבע הזה
- }
- void copy_boards(enum status board1 [7][6], enum status board2 [7][6]){
- for (int i=0; i<7; i++)
- for(int j=0; j<6; j++)
- board1 [i][j] = board2 [i][j];
- }
- int get_from_AI(enum status board [7][6], enum status stat, int Count_of_actions, int diff){
- int loc;
- enum status enemy_color = (stat==white)? black : white;
- //if(Count_of_actions == 42) return -1;
- if (Count_of_actions == 0 || Count_of_actions == 1) return 3; // תור ראשון ושני לשים באמצע
- if (Count_of_actions == 2) return (rand()%3)+2; // אחד משלושת המקומות האמצעיים
- loc = check_for_winning_location(board, stat); // נצח אם אפשר
- if(loc!=-1) return loc;
- loc = check_for_winning_location(board, enemy_color); // חסום ניצחון מיידי של היריב
- if(loc!=-1) return loc;
- if(Count_of_actions == 41) // הוא המהלך האחרון AI אם זה מתקיים אזי המהלך הנוכחי של ה
- return get_first_empty_location(board); // זה מוצא את המקום הפנוי הראשון והיחיד שנותר
- if(diff <= 0) return get_random_location(board);
- if(Count_of_actions >= 3 && Count_of_actions <=6 && diff>3) diff = 3; // כדי שתחילת המשחק לא תהיה איטית
- if(Count_of_actions >= 7 && Count_of_actions <=8 && diff>4) diff = 4;
- int Array_Of_BAD_position[7] = {0}, flag=0; // המערך ממלא ב -1 מקומות שנפסיד אם נשים בהם
- int score=0; // ככל שיותר גבוה פירושו פחות מהלכים נחוצים עד לניצחון
- enum status tmp_board [7][6];
- for(int i=0; i<7; i++){
- int Count_of_actions_TMP = Count_of_actions, diff_TMP = diff;
- copy_boards(tmp_board, board);
- if(tmp_board[i][0]!=empty) continue;
- Put_in_a_move(tmp_board, i, stat);
- Count_of_actions_TMP++;
- goto TAB;
- do{
- Put_in_a_move(tmp_board, get_from_AI(tmp_board, stat, Count_of_actions_TMP, diff-1), stat); // מהלך העתידי שלנו
- Count_of_actions_TMP++;
- if( Victory_check(tmp_board) == stat){
- if(score<diff_TMP) {score = diff_TMP; loc = i;}
- break;
- }
- if(Count_of_actions_TMP == 42) break;
- TAB:
- // מהלך של היריב
- Put_in_a_move(tmp_board, get_from_AI(tmp_board, enemy_color, Count_of_actions_TMP, diff-1), enemy_color); // מהלך העתידי של היריב
- Count_of_actions_TMP++;
- if( Victory_check(tmp_board) == enemy_color){
- Array_Of_BAD_position[i]=-1;
- flag++;
- break;
- }
- if(Count_of_actions_TMP == 42) break;
- diff_TMP--;
- }while(diff_TMP>0);
- }
- if(score>0) return loc;
- /* .כלומר אם יש מקום באמצעותו ננצח בעתיד - נשים שם
- אם יש יותר ממקום אחד לניצחון כזה - נשים במקום שבו הניצחון הכי מהיר */
- // עכשיו נספור כמה עמודות לא מלאות יש
- int OK_LOC=0;
- for(int i=0; i<7; i++){
- if(board[i][0] == empty) OK_LOC++;
- }
- if(OK_LOC == 0) cout<<"ERROR IN OK_LOC\n";
- if(OK_LOC == flag){ //ברמת קושי קטנה ב1 משלנו AI כלומר כל מקום שנשים בו בסופו של דבר נפסיד נגד יריב
- /*
- אפשר להכניס כאן קוד שבוחר את המקום שיש בו
- AI את הסיכויי הכי גבוה לנצח (כלומר את הסיכוי הכי קטן להפסיד) נגד יריב שאינו
- flag ו Array_Of_BAD_position קוד זה צריך לעשות בדיוק את אותה לולאה שעשינו למעלה אבל בלי החלק של
- תיקון:
- לעשות כך שהוא מחשב גם את כמות השלבים עד להפסד עבור כל הפסד.
- אחרי הלולאה הוא בודק
- אם אין בכלל סיכוי לניצחון - עושה את הפעולה להפסד הכי איטי (אם הכל אותו דבר אז עושה אחד מהם) כמובן
- אם יש סיכוי לניצחון:
- אם יש פחות שלבים עד ניצחון אפשרי הכי מהיר מאשר כמות שלבים עד ההפסד הכי מהיר:
- עושה פעולה לניצחון אפשרי הכי מהיר.
- אחרת:
- עושה פעולה להפסד הכי איטי
- */
- /// ניסיון
- int Array[7] = {0}, flag=0;
- int score_bad = Difficulty, score_good = 0, loc_good;
- enum status tmp_board [7][6];
- for(int i=0; i<7; i++){
- int Count_of_actions_TMP = Count_of_actions, diff_TMP = diff;
- copy_boards(tmp_board, board);
- if(tmp_board[i][0]!=empty) continue;
- Put_in_a_move(tmp_board, i, stat);
- Count_of_actions_TMP++;
- goto TAB2;
- do{
- Put_in_a_move(tmp_board, get_from_AI(tmp_board, stat, Count_of_actions_TMP, diff-1), stat); // מהלך העתידי שלנו
- Count_of_actions_TMP++;
- if( Victory_check(tmp_board) == stat){
- if(score_good<diff_TMP) {score_good = diff_TMP; loc_good = i;}
- break;
- }
- if(Count_of_actions_TMP == 42) break;
- TAB2:
- // מהלך של היריב
- Put_in_a_move(tmp_board, get_from_AI(tmp_board, enemy_color, Count_of_actions_TMP, diff-1), enemy_color); // מהלך העתידי של היריב
- Count_of_actions_TMP++;
- diff_TMP--;
- if( Victory_check(tmp_board) == enemy_color){
- if(score_bad>diff_TMP) {score_bad = diff_TMP; loc = i;}
- break;
- }
- if(Count_of_actions_TMP == 42) break;
- }while(diff_TMP>0);
- }
- if(score_good>0) return loc_good;
- if(score_bad<Difficulty) return loc;
- /// עד כאן ניסיון
- //cout<<"Error in nisayon 2\n";
- return get_random_location(board); // זו האפשרות למתכנת העצלן
- }
- if(flag>0) return get_random_location(board, Array_Of_BAD_position); // מקום אקראי שאינו אחד מהמקומות הרעים
- return get_random_location(board); // ייתכן שאפשר לוותר על השורה זאת
- }
- int get_from_AI_with_show(enum status board [7][6], enum status stat, int Count_of_actions, int diff = Difficulty){
- if (stat==white) cout<<"-White AI move...\n";
- else cout<<"-Black AI move...\n";
- //Sleep(1100);
- Sleep(600);
- int location = get_from_AI(board, stat, Count_of_actions, diff);
- cout <<"location (AI): "<<location+1<<"\n\n";
- Beep(540,80);
- return location;
- }
- void main(){
- srand(time(0)); // עבור מספר רנדומלי
- enum status VictoryFlag = empty;
- char strMODE[10];
- reset_board(main_board);
- int Count_of_actions = 0, loc=-1; // לא תציג צבע בלופ ראשון show מאותחל ל -1 כדי שהפונקציה loc המשתנה
- do{
- cout<<"AI or Friend mode (A/F): ";
- cin>>strMODE;
- }while(strMODE[0] != 'a' && strMODE[0] != 'A' && strMODE[0] != 'f' && strMODE[0] != 'F');
- if(strMODE[0] == 'f' || strMODE[0] == 'F'){ // אם זה אדם נגד אדם
- do{
- show(main_board, loc);
- loc = get_from_player(white);
- Put_in_a_move(main_board, loc, white);
- VictoryFlag = Victory_check(main_board);
- if (VictoryFlag != empty) break;
- Count_of_actions++;
- if(Count_of_actions==42) break;
- show(main_board, loc);
- loc = get_from_player(black);
- Put_in_a_move(main_board, loc, black);
- VictoryFlag = Victory_check(main_board);
- if (VictoryFlag != empty) break;
- Count_of_actions++;
- }while(Count_of_actions<42);
- }
- else{ // אם זה אדם נגד מחשב
- do{
- cout<<"Select level [A/B/C/D]: ";
- cin>>strMODE;
- }while(!((strMODE[0] >= 'a' && strMODE[0] <= 'e') || (strMODE[0] >= 'A' && strMODE[0] <= 'E'))); // רק המתכנת יודע שאפשר, אבל מאוד איטי E
- if(strMODE[0] >='A' && strMODE[0] <='Z') Difficulty = strMODE[0] - 'A' + 2;
- else Difficulty = strMODE[0] - 'a' + 2;
- do{
- cout<<"First or second? (F/S): ";
- cin>>strMODE;
- }while(strMODE[0] != 's' && strMODE[0] != 'S' && strMODE[0] != 'f' && strMODE[0] != 'F');
- if(strMODE[0] == 's' || strMODE[0] == 'S') goto S_TART;
- do{
- show(main_board, loc);
- loc = get_from_player(white);
- Put_in_a_move(main_board, loc, white);
- VictoryFlag = Victory_check(main_board);
- if (VictoryFlag != empty) break;
- Count_of_actions++;
- if(Count_of_actions==42) break;
- S_TART:
- show(main_board, loc);
- loc = get_from_AI_with_show(main_board, black, Count_of_actions);
- Put_in_a_move(main_board, loc, black);
- VictoryFlag = Victory_check(main_board);
- if (VictoryFlag != empty) break;
- Count_of_actions++;
- }while(Count_of_actions<42);
- }
- show(main_board, loc);
- if (VictoryFlag==white) {setcolor(11); cout<<"White won!!!!!\n\n\n\n"; setcolor(7);}
- else if (VictoryFlag==black) {setcolor(12); cout<<"Black won!!!!!\n\n\n\n"; setcolor(7);}
- else {setcolor(15); cout<<"End! No win.\n\n\n\n"; setcolor(7);}
- }
Advertisement
Add Comment
Please, Sign In to add comment