日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

<C语言>代码实现与自己创造的“人工智障”进行三子棋对弈,并且艰难的让电脑赢!

發布時間:2024/5/14 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 <C语言>代码实现与自己创造的“人工智障”进行三子棋对弈,并且艰难的让电脑赢! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

文章目錄

前言

一、創建文件項目

二、具體實現步驟

1.呈現菜單,并實現玩家可一直游玩游戲

2.選擇進入游戲后,打印棋盤

?2.1初始化棋盤

?2.2打印棋盤

3.打印棋盤后,玩家和電腦開始輪番下棋

3.1 實現玩家下棋,棋子為 *

3.2 電腦下棋,棋子為 #

4.判斷輸贏

5.整理代碼

總結



前言

????????注意看,這個男人叫小帥,現在,他正在敲代碼實現和機器人下三子棋,終于小帥敲好了代碼,他當即與機器人下了一局,然而小帥發現,這機器人竟然是......


一、創建文件項目

? ? ? ? 時間回到小帥寫代碼時的第一步,小帥首先創建項目以text.c為核心源文件,通過調用game.c和game.h內的函數實現三子棋的所有功能

二、三子棋具體實現步驟

1.呈現菜單,并實現玩家可一直玩游戲

小帥竟然想設置沒有登出建的游戲,由于沒有防沉迷不符合國家規范,那晚,他連夜扛著火車跑路了!

1:代表進入游戲

0:代表退出游戲

? ? ? ? 菜單函數的代碼如下(示例):

//text.c源文件 #include<stdio.h> void menu()//定義菜單函數 {printf("*****************************\n");printf("************1.play***********\n");printf("************0.exit***********\n");printf("*****************************\n"); } void test() {int input = 0;do//該循環實現玩家可以一直游玩三子棋{menu();//調用菜單函數printf("請選擇:>");scanf("%d", &input);//請玩家選擇進入游戲or退出游戲switch (input) //采用switch語句較為便捷{case 1:printf("三子棋\n");break;case 0:printf("退出游戲\n");break;default:printf("選擇錯誤,請重新選擇:\n");break;}} while (input);//0為假,非0為真,即進入游戲輸入1,1作為判斷條件為真,游戲繼續 } int main() {test();return 0; }

? ? ? ? 效果:?

2.選擇進入游戲后,打印棋盤

小帥的目標:打印九宮格簡易棋盤,并且能夠在每個指定格子內存放棋子(即數據)

?2.1初始化棋盤

? ? ? ? 小帥的“頭腦風暴”1:?要在九宮格內存放棋子還要打印在屏幕上,我應該用3*3大小的二維數組?,將每個數組元素發在九宮格的每個格子中間,但是呢,要注意,如果我只將棋盤的形狀打印屏幕上,后續玩家在指定下棋時棋子是不能覆蓋原先屏幕上的符號的,所以我在打印棋盤時就應該保留各個棋子應存放的空間,并存放空格來等待玩家或電腦下的棋子。emm,就是這樣!

????????為了使后續棋盤大小不局限于 3行3列 大小,小帥宏定義ROW 、?COL,如果后續想要改動棋盤大小僅需改變宏定義的ROW 、COL大小即可。宏定義名稱與值時替換關系。

? ? ? ?加上初始化函數的代碼如下(示例):

//game.h頭文件 #define ROW 3 #define COL 3 #include<stdio.h> void InitBoard(char board[ROW][COL], int row, int col); //game.c源文件 #define _CRT_SECURE_NO_WARNINGS #include "game.h"//調用自定義頭文件 void InitBoard(char board[ROW][COL], int row, int col)//定義初始化棋盤函數 {int i = 0, j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = ' ';}} } //text.c源文件 #include "game.h"//調用自定義的頭文件void game()//定義game函數 {//初始化棋盤,用函數實現//傳入數組、行數、列數,以便初始化InitBoard(board, ROW, COL);//數組內全部空格 } void test() {do{menu();printf("請選擇:>");scanf("%d", &input);switch (input){case 1:printf("三子棋\n");game();//游戲的實現!break;case 0:printf("退出游戲\n");break;default:printf("選擇錯誤,請重新選擇:\n");break;}} while (input); } int main() {test();return 0; }

2.2打印棋盤

??????? 小帥發現

棋盤第一行為:

?????????????空格 %c 空格 | 空格 %c 空格 | 空格 %c 空格

最小重復單元,發現為:空格 %c 空格 |要注意的是第三個 | 不需要打印,用if判斷即可

第二行為:

????????????????- - - |?- - - | - - -

最小重復單元,發現為:- - - |,同樣的,要注意的是第三個 | 不需要打印,用條件控制一下即可

并且最后一行無需打印:? - - - |?- - - | - - -

將以上推斷結果封裝為打印函數

? ? ? ? 加上打印函數的代碼如下(示例):

//game.h頭文件 #define ROW 3 #define COL 3 #include<stdio.h> void InitBoard(char board[ROW][COL], int row, int col); void DisplayBoard(char board[ROW][COL], int row, int col); //game.c源文件 #define _CRT_SECURE_NO_WARNINGS #include "game.h" void InitBoard(char board[ROW][COL], int row, int col)//定義//初始化棋盤函數 {int i = 0, j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = ' ';}} } void DisplayBoard(char board[ROW][COL], int row, int col)//定義打印棋盤函數 {int i = 0;int j = 0;for (i = 0; i < row; i++){//1.打印一行數據for (j = 0; j < col; j++){printf(" %c ", board[i][j]);//空格 棋子 空格if (j < col - 1)printf("|");}printf("\n");//2.打印分割行if (i < row - 1){for (j = 0; j < col; j++){printf("---");if(j<col-1)printf("|");}printf("\n");}} } //text.c源文件 #include "game.h"//調用自定義的頭文件 void game()//定義game函數 {//初始化棋盤,用函數實現 并傳入數組、行數、列數,以便初始化InitBoard(board, ROW, COL);//數組內全部空格//打印棋盤DisplayBoard(board, ROW, COL); } void test() {int input = 0;srand((unsigned int)time(NULL));do{menu();printf("請選擇:>");scanf("%d", &input);switch (input){case 1:printf("三子棋\n");game();//游戲的實現!break;case 0:printf("退出游戲\n");break;default:printf("選擇錯誤,請重新選擇:\n");break;}} while (input); } int main() {test();return 0; }

最后每當玩家或電腦下棋后都要更新打印一次棋盤?

3.打印棋盤后,玩家和電腦開始輪番下棋

3.1 實現玩家下棋,棋子為 *

小帥的“頭腦風暴”2:

下棋實質上是為二維數組賦值,而我們賦值時就有了諸多限制:

  • 我要下的格子內是否已經被下過了?
  • 非編程玩家是否知道二維數組第一行和第一列下標是從0開始?
  • 玩家給出的行和列是否超過所給棋盤的大小了?
  • ?

    ?無所謂,小帥會出手!

    所以,我們要解決以上問題

  • 判斷要下的格子內是否已經被下過了,可以判斷該數組元素是否為空格,因為我們之前已經初始化所有數組內容為空格,一旦有棋子落下,該數組元素就會被賦以棋子符號,就不為空格。
  • 玩家默認第一行和列都從1開始,那么我們將玩家輸入的行列數減一即可
  • 這里我們就要有限制條件,玩家給出的行和列應小于等于棋盤的行列數,并且大于等于1。如果不合法,進行提示。
  • ? ? ? ? 玩家下棋函數的代碼如下(示例):

    void PlayerMove(char board[ROW][COL], int row, int col) {int x = 0, y = 0;printf("玩家走:>\n");while (1){printf("請輸入要下的坐標:>");scanf("%d%d", &x, &y);//判斷xy坐標的合法性if (x >= 1 && x <= row && y >= 1 && y <= col){if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else{printf("該坐標被占用\n");}}else{printf("坐標非法,請重新輸入!\n");}} }

    將玩家下棋函數聲明、函數調用、函數定義分別放至game.h、test.c中的game()函數中、game.c中即可。這里為了避免篇幅過長將最后展現全部代碼。?

    3.2 電腦下棋,棋子為 #

    小帥讓電腦隨機下棋,使用srand(time(NULL)),將rand()%row賦值給電腦下棋的行數,將rand()%col賦值給電腦下棋的列數。

    ? ? ? ? 電腦下棋函數的代碼如下(示例)

    void ComputerMove(char board[ROW][COL], int row, int col) {int x = 0, y = 0;printf("電腦走:>\n");while (1){x = rand() % row;y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}} }

    ?將電腦下棋函數聲明、函數調用、函數定義分別放至game.h、test.c中的game()函數中、game.c中即可,將srand(time(NULL))放至test.c的test()函數中。這里為了避免篇幅過長將最后展現全部代碼。?

    4.判斷輸贏

    小帥的頭腦風暴3:

    定義判斷輸贏函數,在玩家和電腦每次下棋后都要判斷一次輸贏

  • 電腦贏返回 #
  • 玩家贏返回 *
  • 平局返回 Q
  • 游戲繼續返回 C
  • 玩家或電腦贏需要滿足三個棋子相同并且連成一條線,注意排除空格情況:

  • 同一行
  • 同一列
  • 對角線
  • 平局情況只需要判斷棋盤是否還剩有空格即可

    ? ? ? ?判斷輸贏函數代碼如下(示例):

    //返回1表示棋盤滿了 //返回0表示棋盤沒滿 int IsFull(char board[ROW][COL], int row, int col) {int i = 0, j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' ')return 0;}}return 1; }char Iswin(char board[ROW][COL], int row, int col) {int i = 0;int j = 0;//橫三行for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' '){return board[i][0];}}//豎三列for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' '){return board[0][i];}}//兩個對角線if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' '){return board[0][0];}if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' '){return board[1][1];}//判斷是否平局if (1 == IsFull(board, ROW, COL)){return 'Q';}elsereturn 'C'; }

    ?將輸贏判斷函數聲明、函數調用、函數定義分別放至game.h、test.c中的game()函數中、game.c中即可。無所謂,小帥會繼續出手!

    5.整理代碼

    //game.h頭文件 #define ROW 3 #define COL 3 #include<stdio.h> #include<stdlib.h> #include<time.h> //聲明 void InitBoard(char board[ROW][COL], int row, int col); void DisplayBoard(char board[ROW][COL], int row, int col); void PlayerMove(char board[ROW][COL],int row,int col); void ComputerMove(char board[ROW][COL],int row,int col); //告訴我們四種狀態 //玩家贏--'* //電腦贏--'# //平局----'Q' //繼續----'C' char Iswin(char board[ROW][COL], int row, int col); //game.c源文件 #define _CRT_SECURE_NO_WARNINGS 1#include "game.h" void InitBoard(char board[ROW][COL], int row, int col) {int i = 0, j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = ' ';}} } void DisplayBoard(char board[ROW][COL], int row, int col) {int i = 0;int j = 0;for (i = 0; i < row; i++){//1.打印一行數據for (j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1)printf("|");}printf("\n");//2.打印分割行if (i < row - 1){for (j = 0; j < col; j++){printf("---");if (j < col - 1)printf("|");}printf("\n");}} } void PlayerMove(char board[ROW][COL], int row, int col) {int x = 0, y = 0;printf("玩家走:>\n");while (1){printf("請輸入要下的坐標:>");scanf("%d%d", &x, &y);//判斷xy坐標的合法性if (x >= 1 && x <= row && y >= 1 && y <= col){if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else{printf("該坐標被占用\n");}}else{printf("坐標非法,請重新輸入!\n");}} } void ComputerMove(char board[ROW][COL], int row, int col) {int x = 0, y = 0;printf("電腦走:>\n");while (1){x = rand() % row;y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}} } //返回1表示棋盤滿了 //返回0表示棋盤沒滿 int IsFull(char board[ROW][COL], int row, int col) {int i = 0, j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' ')return 0;}}return 1; }char Iswin(char board[ROW][COL], int row, int col) {int i = 0;int j = 0;//橫三行for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == board[i][j+1] && board[i][j+1] == board[i][j+2] && board[i][j] != ' '){return board[i][j];}}}//豎三列for (i = 0; i < col; i++){for (j = 0; j < row; j++){if (board[j][i] == board[j+1][i] && board[j+1][i] == board[j+2][i] && board[j][i] != ' '){return board[j][i];}}}//兩個對角線if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' '){return board[0][0];}if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' '){return board[1][1];}//判斷是否平局if (1 == IsFull(board, ROW, COL)){return 'Q';}elsereturn 'C'; } //text.c源文件 #define _CRT_SECURE_NO_WARNINGS //測試三子棋游戲 #include "game.h" #include<stdio.h> void menu() {printf("*****************************\n");printf("************1.play***********\n");printf("************0.exit***********\n");printf("*****************************\n"); }//游戲的整個算法實現 void game() {char ret = 0;//數組-存放走出的棋盤信息char board[ROW][COL] = { ' ' };//數組內全部空格//初始化棋盤,用函數實現InitBoard(board, ROW, COL);//打印棋盤DisplayBoard(board, ROW, COL);//下棋while (1){//玩家下棋PlayerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//判斷玩家是否贏ret = Iswin(board, ROW, COL);if (ret != 'C'){break;}//電腦下棋ComputerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//判斷電腦是否贏ret = Iswin(board, ROW, COL);if (ret != 'C'){break;}}if (ret == '*'){printf("玩家贏\n");}else if (ret == '#'){printf("電腦贏\n");}else if (ret == 'Q'){printf("平局\n");} } void test() {int input = 0;srand((unsigned int)time(NULL));do{menu();printf("請選擇:>");scanf("%d", &input);switch (input){case 1:printf("三子棋\n");game();break;case 0:printf("退出游戲\n");break;default:printf("選擇錯誤,請重新選擇:\n");break;}} while (input); } int main() {test();return 0; }

    效果?


    總結

    ????????小帥的代碼結束,發現自己實現的電腦竟然是個人工智障(給它機會它都不中用的那種),所以我們發現這里有諸多待優化的點,例如:

  • 判斷三連子時,棋盤大小不為3*3,那該如何判斷對角線三連子?
  • 我們是否可以優化電腦,賦以人性,讓它有玩家的思維贏下玩家?
  • 小帥把問題留給我們,這次...他騰不出手了

    ????????最后,如果小伙伴們有優化的方案,請在評論區留言(ps:抱大佬的腿),新手創作,實屬不易,如果滿意,還請給個免費的贊,三連也不是不可以(流口水幻想),嘿!那我們下期再見嘍,拜拜!

    ?

    總結

    以上是生活随笔為你收集整理的<C语言>代码实现与自己创造的“人工智障”进行三子棋对弈,并且艰难的让电脑赢!的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。