一.如何实现
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("玩家走: "); printf("请输入坐标: "); 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("坐标被占用,请重新输入 "); } } else { printf("坐标非法,请重新输入 "); } } }
玩家下子主要采用的思路是,判断棋盘上是否有子,已经输入的坐标是否合法。
(4)电脑下子
void ComputerMove(char board[ROW][COL], int row, int col) { int x, y; printf("电脑走 "); 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("************************** "); printf("******* 1. play ********* "); printf("******* 0. exit ********* "); printf("************************** "); } 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("玩家赢 "); else if (ret == "x") printf("电脑赢 "); else printf("平局 "); } int main() { int input; srand((unsigned int)time(NULL)); do { menu(); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏 "); break; default: printf("选择错误 "); 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(" "); 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(" "); //打印分割行 if (i < row - 1) { printf(" "); for (int j = 0;j < col;j++) { printf("---"); if (j < col-1) printf("|"); } printf(" "); } } } void PlayerMove(char board[ROW][COL], int row, int col) { int x, y; while (1) { printf("玩家走: "); printf("请输入坐标: "); 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("坐标被占用,请重新输入 "); } } else { printf("坐标非法,请重新输入 "); } } } void ComputerMove(char board[ROW][COL], int row, int col) { int x, y; printf("电脑走 "); 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五子棋内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/Ja_king_/article/details/119183595