如何利用最簡單的C語言實現AI五子棋
一.如何實現
1.說明:由於本文隻是對初學C語言的人學習,所以將不會涉及任何算法,電腦將采用隨機下子的方式。(後期會為大傢介紹Alpha-Beta剪枝算法實現人工智能AI)
2.主要部分:
(1)菜單
(2)打印棋盤
(3)玩傢下子
(4)電腦下子
(5)判斷輸贏
二.實現代碼及分析
(1)菜單的制作
運用do…while循環調用菜單,根據用戶選擇實現玩遊戲和退出遊戲
(2)棋盤的初始化和打印
棋盤采用標準的15*15的格子,我們可以宏定義ROW和COL分別為15和15來表示行和列。
分別封裝兩個函數對棋盤進行初始化和打印
初始化:(這裡將棋盤初始化為空格,可初始化為其他)
打印棋盤:
效果如下:
(3)玩傢下子
void PlayerMove(char board[ROW][COL], int row, int col) { int x, y; while (1) { printf("玩傢走:\n"); printf("請輸入坐標:\n"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = 'O'; break; } else { printf("坐標被占用,請重新輸入\n"); } } else { printf("坐標非法,請重新輸入\n"); } } }
玩傢下子主要采用的思路是,判斷棋盤上是否有子,已經輸入的坐標是否合法。
(4)電腦下子
void ComputerMove(char board[ROW][COL], int row, int col) { int x, y; printf("電腦走\n"); while (1) { x = rand() % row; y = rand() % col; if (board[x][y] == ' ') { board[x][y] = 'X'; break; } } }
與玩傢下子相同,此處采用的隨機下子,後期可進行優化(比如:極大極小值算法、Alpha-Beta剪枝算法等)
(5)判斷輸贏
通過遍歷整個棋盤,觀察是否有連五子情況出現,代碼如下:
char iswin(char board[ROW][COL], int row, int col) { //行 int ren=0,dian=0,i,j; for (i = 0;i < row;i++) { ren = 0; for (j = 0;j < col;j++) { if (board[i][j] == 'O') ren++; else ren = 0; if (ren >= 5) return 'o'; } } for (i = 0;i < row;i++) { dian = 0; for (j = 0;j < col;j++) { if (board[i][j] == 'X') dian++; else dian = 0; if (dian >= 5) return 'x'; } } //列 ren = dian = 0; for (i = 0;i < row;i++) { ren = 0; for (j = 0;j < col;j++) { if (board[j][i] == 'O') ren++; else ren = 0; if (ren >= 5) return 'o'; } } for (i = 0;i < row;i++) { dian = 0; for (j = 0;j < col;j++) { if (board[j][i] == 'X') dian++; else dian = 0; if (dian >= 5) return 'x'; } } //右下 ren = dian =i=j= 0; for (int k = 0;k < row;k++) { i = k; j = 0; ren = 0; while (i < row && j < col) { if (board[i][j] == 'O') { ren++; } else { ren = 0; } i++; j++; if (ren >= 5) return 'o'; } } i = j = 0; for (int k = 0;k < row;k++) { i = k; j = 0; dian = 0; while (i < row && j < col) { if (board[i][j] == 'X') { dian++; } else dian = 0; i++; j++; if (dian >= 5) return 'x'; } } //右上 for (int k = row;k >=0;k--) { j = col; i = k; ren = 0; while (i >=0 && j >=0) { if (board[i][j] == 'O') { ren++; } else ren = 0; i--; j--; if (ren >= 5) return 'o'; } } for (int k = row;k >= 0;k--) { i = k; j = col; dian = 0; while (i >= 0 && j >= 0) { if (board[i][j] == 'X') { dian++; } else dian = 0; i--; j--; if (dian >= 5) return 'o'; } } for (int k = row;k >= 0;k--) { i = k; j = 0; dian = 0; while (i >= 0 && j <col) { if (board[i][j] == 'O') { dian++; } else dian = 0; i--; j++; if (dian >= 5) return 'o'; } } for (int k = row;k >= 0;k--) { i = k; j = 0; dian = 0; while (i >= 0 && j <col) { if (board[i][j] == 'X') { dian++; } else dian = 0; i--; j++; if (dian >= 5) return 'x'; } } for (int k = 0;k < row;k++) { i = k; j = col; dian = 0; while (i < row && j >= 0) { if (board[i][j] == 'O') { dian++; } else dian = 0; i++; j--; if (dian >= 5) return 'o'; } } for (int k = 0;k <row;k++) { i = k; j = col; dian = 0; while (i <row && j >= 0) { if (board[i][j] == 'X') { dian++; } else dian = 0; i++; j--; if (dian >= 5) return 'x'; } } for (int k = row;k >= 0;k--) { i = k; j = 0; dian = 0; while (i >= 0 && j <col) { if (board[i][j] == 'O') { dian++; } else dian = 0; i--; j++; if (dian >= 5) return 'o'; } } for (int k = row;k >= 0;k--) { i = k; j = 0; dian = 0; while (i >= 0 && j <col) { if (board[i][j] == 'X') { dian++; } else dian = 0; i--; j++; if (dian >= 5) return 'x'; } } for (int k = 0;k < row;k++) { i = k; j = col; dian = 0; while (i < row && j >= 0) { if (board[i][j] == 'O') { dian++; } else dian = 0; i++; j--; if (dian >= 5) return 'o'; } } for (int k = 0;k <row;k++) { i = k; j = col; dian = 0; while (i <row && j >= 0) { if (board[i][j] == 'X') { dian++; } else dian = 0; i++; j--; if (dian >= 5) return 'x'; } } return 'c'; //左 }
三.整個代碼
(1)test.c文件下代碼:
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void menu() { printf("**************************\n"); printf("******* 1. play *********\n"); printf("******* 0. exit *********\n"); printf("**************************\n"); } void game() { //棋盤數組 char board[ROW][COL],ret; //初始化棋盤 InitBoard(board, ROW, COL); //打印棋盤 PrintBoard(board, ROW, COL); //下棋 int a; printf("1.先手 0.後手"); scanf("%d", &a); if(a==1) PlayerMove(board, ROW, COL); else ComputerMove(board, ROW, COL); while (1) { if (a == 0) { //PlayerMove(board, ROW, COL); PlayerMove(board, ROW, COL); PrintBoard(board, ROW, COL); ret=iswin(board, ROW, COL); if (ret != 'c') { break; } //ComputerMove(board, ROW, COL); ComputerMove(board, ROW, COL); PrintBoard(board, ROW, COL); ret = iswin(board, ROW, COL); if (ret != 'c') { break; } } else { //ComputerMove(board, ROW, COL); ComputerMove(board, ROW, COL); PrintBoard(board, ROW, COL); ret = iswin(board, ROW, COL); if (ret != 'c') { break; } //PlayerMove(board, ROW, COL); PlayerMove(board, ROW, COL); PrintBoard(board, ROW, COL); ret = iswin(board, ROW, COL); if (ret != 'c') { break; } } } if (ret == 'o') printf("玩傢贏\n"); else if (ret == 'x') printf("電腦贏\n"); else printf("平局\n"); } int main() { int input; srand((unsigned int)time(NULL)); do { menu(); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出遊戲\n"); break; default: printf("選擇錯誤\n"); break; } } while (input); return 0; }
(2)game.c下的代碼
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void InitBoard(char board[ROW][COL], int row, int col) { for (int i = 0;i < row;i++) { for (int j = 0;j < col;j++) { board[i][j] = ' '; } } } void PrintBoard(char board[ROW][COL], int row, int col) { for (int i = 0;i < row;i++) { printf(" "); printf("%2d", i+1); } printf("\n"); for (int i = 0;i < row;i++) { //打印數據 printf("%2d", i + 1); for (int j = 0;j < col;j++) { printf(" %c ", board[i][j]); if (j < col - 1) printf("|"); } printf("\n"); //打印分割行 if (i < row - 1) { printf(" "); for (int 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, y; while (1) { printf("玩傢走:\n"); printf("請輸入坐標:\n"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = 'O'; break; } else { printf("坐標被占用,請重新輸入\n"); } } else { printf("坐標非法,請重新輸入\n"); } } } void ComputerMove(char board[ROW][COL], int row, int col) { int x, y; printf("電腦走\n"); while (1) { x = rand() % row; y = rand() % col; if (board[x][y] == ' ') { board[x][y] = 'X'; break; } } } char iswin(char board[ROW][COL], int row, int col) { //行 int ren=0,dian=0,i,j; for (i = 0;i < row;i++) { ren = 0; for (j = 0;j < col;j++) { if (board[i][j] == 'O') ren++; else ren = 0; if (ren >= 5) return 'o'; } } for (i = 0;i < row;i++) { dian = 0; for (j = 0;j < col;j++) { if (board[i][j] == 'X') dian++; else dian = 0; if (dian >= 5) return 'x'; } } //列 ren = dian = 0; for (i = 0;i < row;i++) { ren = 0; for (j = 0;j < col;j++) { if (board[j][i] == 'O') ren++; else ren = 0; if (ren >= 5) return 'o'; } } for (i = 0;i < row;i++) { dian = 0; for (j = 0;j < col;j++) { if (board[j][i] == 'X') dian++; else dian = 0; if (dian >= 5) return 'x'; } } //右下 ren = dian =i=j= 0; for (int k = 0;k < row;k++) { i = k; j = 0; ren = 0; while (i < row && j < col) { if (board[i][j] == 'O') { ren++; } else { ren = 0; } i++; j++; if (ren >= 5) return 'o'; } } i = j = 0; for (int k = 0;k < row;k++) { i = k; j = 0; dian = 0; while (i < row && j < col) { if (board[i][j] == 'X') { dian++; } else dian = 0; i++; j++; if (dian >= 5) return 'x'; } } //右上 for (int k = row;k >=0;k--) { j = col; i = k; ren = 0; while (i >=0 && j >=0) { if (board[i][j] == 'O') { ren++; } else ren = 0; i--; j--; if (ren >= 5) return 'o'; } } for (int k = row;k >= 0;k--) { i = k; j = col; dian = 0; while (i >= 0 && j >= 0) { if (board[i][j] == 'X') { dian++; } else dian = 0; i--; j--; if (dian >= 5) return 'o'; } } for (int k = row;k >= 0;k--) { i = k; j = 0; dian = 0; while (i >= 0 && j <col) { if (board[i][j] == 'O') { dian++; } else dian = 0; i--; j++; if (dian >= 5) return 'o'; } } for (int k = row;k >= 0;k--) { i = k; j = 0; dian = 0; while (i >= 0 && j <col) { if (board[i][j] == 'X') { dian++; } else dian = 0; i--; j++; if (dian >= 5) return 'x'; } } for (int k = 0;k < row;k++) { i = k; j = col; dian = 0; while (i < row && j >= 0) { if (board[i][j] == 'O') { dian++; } else dian = 0; i++; j--; if (dian >= 5) return 'o'; } } for (int k = 0;k <row;k++) { i = k; j = col; dian = 0; while (i <row && j >= 0) { if (board[i][j] == 'X') { dian++; } else dian = 0; i++; j--; if (dian >= 5) return 'x'; } } return 'c'; //左 }
(3)game.h下的代碼
#pragma once #define ROW 15 #define COL 15 #include<stdio.h> #include<stdlib.h> #include<time.h> //初始化棋盤 void InitBoard(char board[ROW][COL], int row, int col); //打印棋盤 void PrintBoard(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); //判斷輸贏 char iswin(char board[ROW][COL], int row, int col);
四.具體效果
1.棋盤打印以及選擇先後手
2.玩傢和電腦下子
3.判斷輸贏
此處我們看到玩傢贏瞭,可是電腦實在太蠢瞭,所以還有很多地方需要添加的
歡迎各位大佬對此代碼進行優化!
總結
到此這篇關於如何利用最簡單的C語言實現AI五子棋的文章就介紹到這瞭,更多相關C語言實現AI五子棋內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!