三子棋的实现,人工智能与人工智障
1.菜單
我們先進行菜單打印的實現,如下:
void menu() {printf("**********************************************\n");printf("************ 1.play ************\n");printf("************ 0.exit ************\n");printf("**********************************************\n"); }菜單要求我們進行輸出1/0,但是我們要考慮玩家可能輸錯的情況所以我們用switch語句來對玩家的輸入進行一個反饋,如下:
int input = 0;do{menu();printf("請輸入(1/0):");scanf("%d", &input);switch (input){case 1:printf("開始游戲\n");game();break;case 0:printf("退出游戲\n");break;default:printf("輸入錯誤,請重新輸入\n");break;}} while (input);上面這段代碼是在主函數中實現的,當然你也可將其打包到一個函數中,這里就不做展示了。
當玩家輸入1時,進入游戲,下面我們來實現game里的內容。
2.初始化棋盤與打印棋盤
玩家要想玩三子棋首先肯定要有一個棋盤,三子棋的棋盤一共有9個空位,玩家將在這些空位上下棋,在游戲的過程中,我們是需要對玩家和電腦的下棋情況進行收錄的,所以我們先創建一個數組,在里面全部初始化為 空格 ,實現如下:
void InitBoard(char board[ROW][COL], int row, int col)//初始化棋盤 {int i, j;for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = ' ';}} } void game() {int ret = 1;int n = 0;char board[ROW][COL] = { 0 };InitBoard(board, ROW, COL);DisplayBoard(board, ROW, COL); }這里要說明一下,ROW代表的是行,COL代表的是列,這是提前用define設置好的,后面會提到,row和col也是一樣的意思,傳過來是為了方便。
之后是打印棋盤,思路其實還是蠻簡單的,循環加判斷,相信大家都是可以理解的,就不細說明了,實現如下:
void DisplayBoard(char board[ROW][COL], int row, int col)//打印棋盤 {int i, j;for (i = 0; i < row; i++){for (j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1){printf("|");} //“ |”這是一次循環} //當打印最后一次時不打印“|”//打印出來是 | | printf("\n");if (i < row - 1){for (j = 0; j < col; j++){printf("---");if (j < col - 1){printf("|");//“---|”是一次循環} //打印最后一次時不打印“|”} //打印出來是---|---|---}printf("\n");// 上面的兩行加一起是一次循環} //最后一次循環不打印---| }//打印出來是這樣的效果 // | | //---|---|--- // | | //---|---|--- // | |而設置ROW和COL的目的就是將棋盤的打印變得可控,可以操控棋盤的大小。
3.玩家下棋和電腦下棋
玩家下棋很簡單,玩家輸入坐標(1~3)(1~3)后判斷此位置是否有棋子,如果有則讓其在輸入一次,如果沒有則記錄下來,放到之前創建的數組board里。
void PlayMove(char board[ROW][COL], int row, int col)//玩家下棋 {int x, y;printf("玩家輸入\n");while (1){printf("請輸入坐標:");scanf("%d %d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col&&board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else if (x <= 0 || x > row || y <= 0 || y > col){printf("坐標非法,請重新輸入\n");}else if (board[x - 1][y - 1] != ' '){printf("該坐標已被占用,請選擇其他坐標\n");}} }電腦下棋我們將簡單模式設置為隨機下棋,下面是實現:
void ComputerMove0(char board[ROW][COL], int row, int col) {Sleep(200);printf("電腦下棋\n");int x, y;while (1){x = rand() % row + 1;y = rand() % col + 1;if (board[x][y] == ' '){board[x][y] = '#';break;}} }隨機數的概念在《猜數字游戲》這篇博客里有說,這里就不細說明了。
簡單的人機肯定不是我們想要的,那么復雜的人機該怎么實現呢?
很簡單,三子棋玩的好的小伙伴們都知道,如果雙方都是高手在不出失誤的情況下是只能平局的,實現起來也好辦,把情況都列舉出來就好了,但是這樣不僅玩家沒有良好的游戲體驗,代碼也繁重,所以我們僅讓電腦判斷:
(下面是按照優先序排列的)
1)如果己方(電腦)在橫排、豎排、斜排已有兩個棋子,如果剩下的位置沒有棋子,則下在此處
2)如果對方(玩家)在橫排、豎排、斜排已有兩個棋子,如果剩下的位置沒有棋子,則下在此處
3)如果以上情況都沒有那么中間優先下,沒有則下四角,如果都沒有空位,那么隨機下。
下面是實現:
int ComputerMove1(char board[ROW][COL], int row, int col) {int i = 0, j = 0, m = 1,n = 1;printf("電腦輸入\n");while(i < row)//判斷電腦是否有兩個{if (board[i][0] == '#' && board[i][1] == '#' && board[i][2] == ' '){board[i][2] = '#';return 1;}if (board[i][0] == '#' && board[i][2] == '#' && board[i][1] == ' '){board[i][1] = '#';return 1;}if (board[i][1] == '#' && board[i][2] == '#' && board[i][0] == ' '){board[i][0] = '#';return 1;}if (board[0][j] == '#' && board[1][j] == '#' && board[2][j] == ' '){board[2][j] = '#';return 1;}if (board[0][j] == '#' && board[2][j] == '#' && board[1][j] == ' '){board[1][j] = '#';return 1;}if (board[1][j] == '#' && board[2][j] == '#' && board[0][j] == ' '){board[0][j] = '#';return 1;}i++;j++;}i = 0;j = 0;while (i < col)//判斷玩家是否有兩個{if (board[i][0] == '*' && board[i][1] == '*' && board[i][2] == ' '){board[i][2] = '#';return 1;}if (board[i][0] == '*' && board[i][2] == '*' && board[i][1] == ' '){board[i][1] = '#';return 1;}if (board[i][1] == '*' && board[i][2] == '*' && board[i][0] == ' '){board[i][0] = '#';return 1;}if (board[0][j] == '*' && board[1][j] == '*' && board[2][j] == ' '){board[2][j] = '#';return 1;}if (board[0][j] == '*' && board[2][j] == '*' && board[1][j] == ' '){board[1][j] = '#';return 1;}if (board[1][j] == '*' && board[2][j] == '*' && board[0][j] == ' '){board[0][j] = '#';return 1;}i++;j++;}if (board[1][1] == ' ')//中間{board[1][1] = '#';return 1;}else if (board[1][1] != ' ')//四角{if (board[0][0] == ' '){board[0][0] = '#';return 1;}else if (board[0][2] == ' '){board[0][2] = '#';return 1;}else if (board[2][0] == ' '){board[2][0] = '#';return 1;}else if (board[2][2] == ' '){board[2][2] = '#';return 1;}}else//隨機{int x, y;while (1){x = rand() % row + 1;y = rand() % col + 1;if (board[x][y] == ' '){board[x][y] = '#';break;}}return 1;} }這樣一個困難的電腦就產生了。
4.判斷輸贏
我們需要在每次下棋(玩家或電腦)后進行判斷輸贏,如果玩家有三顆棋子連在一起,則玩家贏,如果電腦有三顆連在一起則電腦贏,如果棋盤滿了也沒有輸贏則平局。
如果贏了或者平局則返回0,在game里判斷是否返回0,如果是則結束本場游戲
下面是實現:
InitBoard(board, ROW, COL);//初始化棋盤 DisplayBoard(board, ROW, COL);//打印棋盤 while (1) {PlayMove(board, ROW, COL);//玩家下棋DisplayBoard(board, ROW, COL);//打印棋盤ret = who_win(board, ROW, COL);//判斷輸贏if (ret == 0)break;ComputerMove0(board, ROW, COL);//電腦下棋DisplayBoard(board, ROW, COL);//打印棋盤ret = who_win(board, ROW, COL);//判斷輸贏if (ret == 0)break; } int who_win(char board[ROW][COL],int row, int col) {int i, j, count = 0;for (i = 0; i < row; i++){if (board[i][0] == '*' && board[i][1] == '*' && board[i][2] == '*'){printf("玩家贏\n");Sleep(2000);system("cls");return 0;}if (board[i][0] == '#' && board[i][1] == '#' && board[i][2] == '#'){printf("電腦贏\n");Sleep(2000);system("cls");return 0;}}for (i = 0; i < col; i++){if (board[0][i] == '*' && board[1][i] == '*' && board[2][i] == '*'){printf("玩家贏\n");Sleep(2000);system("cls");return 0;}if (board[0][i] == '#' && board[1][i] == '#' && board[2][i] == '#'){printf("電腦贏\n");Sleep(2000);system("cls");return 0;}}if ((board[0][0] == '*' && board[1][1] == '*' && board[2][2] == '*') || (board[0][2] == '*' && board[1][1] == '*' && board[2][0] == '*')){printf("玩家贏\n");Sleep(2000);system("cls");return 0;}if ((board[0][0] == '#' && board[1][1] == '#' && board[2][2] == '#') || (board[0][2] == '#' && board[1][1] == '#' && board[2][0] == '#')){printf("電腦贏\n");Sleep(2000);system("cls");return 0;}for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] != ' '){count++;}}}if (count == row * col){printf("平局了\n");Sleep(2000);system("cls");return 0;}return 1; }還有難度的選擇,判斷即可,下面是源代碼(我是分文件寫的):
主文件:
#define _CRT_SECURE_NO_WARNINGS #include "game.h" void menu() {printf("**********************************************\n");printf("************ 1.play ************\n");printf("************ 0.exit ************\n");printf("**********************************************\n"); }void game() {int ret = 1;int n = 0;char board[ROW][COL] = { 0 };printf("請選擇難度(0.簡單/1.困難):");scanf("%d", &n);if (n == 0){InitBoard(board, ROW, COL);//初始化棋盤DisplayBoard(board, ROW, COL);//打印棋盤while (1){PlayMove(board, ROW, COL);//玩家下棋DisplayBoard(board, ROW, COL);//棋盤ret = who_win(board, ROW, COL);//判斷輸贏if (ret == 0)break;ComputerMove0(board, ROW, COL);//電腦下棋DisplayBoard(board, ROW, COL);//棋盤ret = who_win(board, ROW, COL);//判斷輸贏if (ret == 0)break;}}else if (n == 1){InitBoard(board, ROW, COL);DisplayBoard(board, ROW, COL);while (1){PlayMove(board, ROW, COL);DisplayBoard(board, ROW, COL);ret = who_win(board, ROW, COL);if (ret == 0)break;ComputerMove1(board, ROW, COL);DisplayBoard(board, ROW, COL);ret = who_win(board, ROW, COL);if (ret == 0)break;}}else{printf("輸入錯誤,默認選簡單\n");InitBoard(board, ROW, COL);DisplayBoard(board, ROW, COL);while (1){PlayMove(board, ROW, COL);DisplayBoard(board, ROW, COL);ret = who_win(board, ROW, COL);if (ret == 0)break;ComputerMove0(board, ROW, COL);DisplayBoard(board, ROW, COL);ret = who_win(board, ROW, COL);if (ret == 0)break;}} } int main() {srand((unsigned int)time(NULL));int input = 0;do{menu();printf("請輸入(1/0):");scanf("%d", &input);switch (input){case 1:printf("開始游戲\n");game();break;case 0:printf("退出游戲\n");break;default:printf("輸入錯誤,請重新輸入\n");break;}} while (input);return 0; }game.h頭文件:
#pragma once #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <time.h> #include <windows.h>#define ROW 3 #define COL 3void InitBoard(char board[ROW][COL], int row, int col); void DisplayBoard(char board[ROW][COL], int row, int col); void PlayMove(char board[ROW][COL], int row, int col); void ComputerMove0(char board[ROW][COL], int row, int col); int ComputerMove1(char board[ROW][COL], int row, int col); int who_win(char board[ROW][COL], int row, int col);game.cpp存放函數實現的文件:
#include "game.h"void InitBoard(char board[ROW][COL], int row, int col)//初始化棋盤 {int i, j;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, j;for (i = 0; i < row; i++){for (j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1){printf("|");}}printf("\n");if (i < row - 1){for (j = 0; j < col; j++){printf("---");if (j < col - 1){printf("|");}}}printf("\n");} }void PlayMove(char board[ROW][COL], int row, int col)//玩家下棋 {int x, y;printf("玩家輸入\n");while (1){printf("請輸入坐標:");scanf("%d %d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col&&board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else if (x <= 0 || x > row || y <= 0 || y > col){printf("坐標非法,請重新輸入\n");}else if (board[x - 1][y - 1] != ' '){printf("該坐標已被占用,請選擇其他坐標\n");}} }void ComputerMove0(char board[ROW][COL], int row, int col)//簡單電腦 {Sleep(200);printf("電腦下棋\n");int x, y;while (1){x = rand() % row + 1;y = rand() % col + 1;if (board[x][y] == ' '){board[x][y] = '#';break;}} }int ComputerMove1(char board[ROW][COL], int row, int col)//困難電腦 {int i = 0, j = 0, m = 1,n = 1;printf("電腦輸入\n");while(i < row){if (board[i][0] == '#' && board[i][1] == '#' && board[i][2] == ' '){board[i][2] = '#';return 1;}if (board[i][0] == '#' && board[i][2] == '#' && board[i][1] == ' '){board[i][1] = '#';return 1;}if (board[i][1] == '#' && board[i][2] == '#' && board[i][0] == ' '){board[i][0] = '#';return 1;}if (board[0][j] == '#' && board[1][j] == '#' && board[2][j] == ' '){board[2][j] = '#';return 1;}if (board[0][j] == '#' && board[2][j] == '#' && board[1][j] == ' '){board[1][j] = '#';return 1;}if (board[1][j] == '#' && board[2][j] == '#' && board[0][j] == ' '){board[0][j] = '#';return 1;}i++;j++;}i = 0;j = 0;while (i < col){if (board[i][0] == '*' && board[i][1] == '*' && board[i][2] == ' '){board[i][2] = '#';return 1;}if (board[i][0] == '*' && board[i][2] == '*' && board[i][1] == ' '){board[i][1] = '#';return 1;}if (board[i][1] == '*' && board[i][2] == '*' && board[i][0] == ' '){board[i][0] = '#';return 1;}if (board[0][j] == '*' && board[1][j] == '*' && board[2][j] == ' '){board[2][j] = '#';return 1;}if (board[0][j] == '*' && board[2][j] == '*' && board[1][j] == ' '){board[1][j] = '#';return 1;}if (board[1][j] == '*' && board[2][j] == '*' && board[0][j] == ' '){board[0][j] = '#';return 1;}i++;j++;}if (board[1][1] == ' '){board[1][1] = '#';return 1;}else if (board[1][1] != ' '){if (board[0][0] == ' '){board[0][0] = '#';return 1;}else if (board[0][2] == ' '){board[0][2] = '#';return 1;}else if (board[2][0] == ' '){board[2][0] = '#';return 1;}else if (board[2][2] == ' '){board[2][2] = '#';return 1;}}else{int x, y;while (1){x = rand() % row + 1;y = rand() % col + 1;if (board[x][y] == ' '){board[x][y] = '#';break;}}return 1;} }int who_win(char board[ROW][COL],int row, int col)//判斷輸贏 {int i, j, count = 0;for (i = 0; i < row; i++){if (board[i][0] == '*' && board[i][1] == '*' && board[i][2] == '*'){printf("玩家贏\n");Sleep(2000);system("cls");return 0;}if (board[i][0] == '#' && board[i][1] == '#' && board[i][2] == '#'){printf("電腦贏\n");Sleep(2000);system("cls");return 0;}}for (i = 0; i < col; i++){if (board[0][i] == '*' && board[1][i] == '*' && board[2][i] == '*'){printf("玩家贏\n");Sleep(2000);system("cls");return 0;}if (board[0][i] == '#' && board[1][i] == '#' && board[2][i] == '#'){printf("電腦贏\n");Sleep(2000);system("cls");return 0;}}if ((board[0][0] == '*' && board[1][1] == '*' && board[2][2] == '*') || (board[0][2] == '*' && board[1][1] == '*' && board[2][0] == '*')){printf("玩家贏\n");Sleep(2000);system("cls");return 0;}if ((board[0][0] == '#' && board[1][1] == '#' && board[2][2] == '#') || (board[0][2] == '#' && board[1][1] == '#' && board[2][0] == '#')){printf("電腦贏\n");Sleep(2000);system("cls");return 0;}for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] != ' '){count++;}}}if (count == row * col){printf("平局了\n");Sleep(2000);system("cls");return 0;}return 1; }以上就是三子棋的全部內容了。
總結
以上是生活随笔為你收集整理的三子棋的实现,人工智能与人工智障的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无人驾驶汽车入门_无人驾驶汽车将如何扭转
- 下一篇: RNG牛掰!