??上篇博客對三子棋小游戲進行了升級,但僅是擴展到了多子棋,電腦演算法采用的還是偽亂數的方法,電腦還是個憨憨,
??那么今天就對三子棋小游戲中電腦下棋演算法進行一次優化吧,多子棋演算法優化改變相應模塊條件就可以實作,
文章目錄
- 游戲測驗
- 電腦是否能贏
- 玩家是否能贏
- 新的ComputerMove函式
- 新的game函式
- 完整程式
- 寫在后面
游戲測驗
****************************************
*****1.開始游戲 0.退出游戲*****
****************************************
系統提示:請選擇:>>>1
1 2 3
1 | |
---|---|---
2 | |
---|---|---
3 | |
系統提示:請輸入您要下的坐標:>>>1 2
1 2 3
1 | * |
---|---|---
2 | |
---|---|---
3 | |
電腦:我走過啦!!!到你啦!!!
1 2 3
1 | * |
---|---|---
2 | |
---|---|---
3 | | #
系統提示:請輸入您要下的坐標:>>>2 2
1 2 3
1 | * |
---|---|---
2 | * |
---|---|---
3 | | #
電腦:我走過啦!!!到你啦!!!
1 2 3
1 | * |
---|---|---
2 | * |
---|---|---
3 | # | #
系統提示:請輸入您要下的坐標:>>>3 1
1 2 3
1 | * |
---|---|---
2 | * |
---|---|---
3 * | # | #
電腦:我走過啦!!!到你啦!!!
1 2 3
1 | * | #
---|---|---
2 | * |
---|---|---
3 * | # | #
系統提示:請輸入您要下的坐標:>>>2 3
1 2 3
1 | * | #
---|---|---
2 | * | *
---|---|---
3 * | # | #
電腦:我走過啦!!!到你啦!!!
1 2 3
1 | * | #
---|---|---
2 # | * | *
---|---|---
3 * | # | #
系統提示:請輸入您要下的坐標:>>>1 1
1 2 3
1 * | * | #
---|---|---
2 # | * | *
---|---|---
3 * | # | #
平局!!!嗯嗯,你已經不錯了,但還要加油哦!
****************************************
*****1.開始游戲 0.退出游戲*****
****************************************
系統提示:請選擇:>>>1
1 2 3
1 | |
---|---|---
2 | |
---|---|---
3 | |
系統提示:請輸入您要下的坐標:>>>2 2
1 2 3
1 | |
---|---|---
2 | * |
---|---|---
3 | |
電腦:我走過啦!!!到你啦!!!
1 2 3
1 | |
---|---|---
2 | * |
---|---|---
3 | # |
系統提示:請輸入您要下的坐標:>>>1 1
1 2 3
1 * | |
---|---|---
2 | * |
---|---|---
3 | # |
電腦:我走過啦!!!到你啦!!!
1 2 3
1 * | |
---|---|---
2 | * |
---|---|---
3 | # | #
系統提示:請輸入您要下的坐標:>>>1 3
1 2 3
1 * | | *
---|---|---
2 | * |
---|---|---
3 | # | #
電腦:我走過啦!!!到你啦!!!
1 2 3
1 * | | *
---|---|---
2 | * |
---|---|---
3 # | # | #
你輸了!!!emmm,不過沒關系,畢竟你是人類哇!
****************************************
*****1.開始游戲 0.退出游戲*****
****************************************
系統提示:請選擇:>>>1
****************************************
*****1.開始游戲 0.退出游戲*****
****************************************
系統提示:請選擇:>>>1
1 2 3
1 | |
---|---|---
2 | |
---|---|---
3 | |
系統提示:請輸入您要下的坐標:>>>2 2
1 2 3
1 | |
---|---|---
2 | * |
---|---|---
3 | |
電腦:我走過啦!!!到你啦!!!
1 2 3
1 | |
---|---|---
2 | * |
---|---|---
3 | | #
系統提示:請輸入您要下的坐標:>>>1 1
1 2 3
1 * | |
---|---|---
2 | * |
---|---|---
3 | | #
電腦:我走過啦!!!到你啦!!!
1 2 3
1 * | |
---|---|---
2 | * |
---|---|---
3 | # | #
系統提示:請輸入您要下的坐標:>>>3 1
1 2 3
1 * | |
---|---|---
2 | * |
---|---|---
3 * | # | #
電腦:我走過啦!!!到你啦!!!
1 2 3
1 * | |
---|---|---
2 # | * |
---|---|---
3 * | # | #
系統提示:請輸入您要下的坐標:>>>1 3
1 2 3
1 * | | *
---|---|---
2 # | * |
---|---|---
3 * | # | #
恭喜你贏啦!!!哇哦,太棒了!沒幾個人能戰勝我呢!)
****************************************
*****1.開始游戲 0.退出游戲*****
****************************************
系統提示:請選擇:>>>
??這次程式中添加了兩個函式check_computer、judge_player且對ComputerMove和game兩個函式以及頭檔案做出了更改,頭檔案僅添加了這兩個新增函式的宣告,
??下面介紹兩個新增函式,
電腦是否能贏
??電腦是否能贏,在下過一兩個或者多個回合的時候,這個函式真正起到作用,如果能贏就落子,
//判斷電腦自己是否有機會贏,如果能贏,就落子,因為自己贏的優先級肯定大于攔截對手,對吧
int check_computer(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
int k = 0;
while (0 == k)
{
//判斷電腦橫行上是否會贏
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == '#' && board[i][2] == ' ')
{
board[i][2] = '#';
k = 1;
break;
}
if (board[i][0] == board[i][2] && board[i][0] == '#' && board[i][1] == ' ')
{
board[i][1] = '#';
k = 1;
break;
}
if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' ')
{
board[i][0] = '#';
k = 1;
break;
}
}
if (k != 0)
break;
//判斷電腦列上是否有機會贏
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == '#' && board[2][j] == ' ')
{
board[2][j] = '#';
k = 1;
break;
}
if (board[0][j] == board[2][j] && board[2][j] == '#' && board[1][j] == ' ')
{
board[1][j] = '#';
k = 1;
break;
}
if (board[1][j] == board[2][j] && board[2][j] == '#' && board[0][j] == ' ')
{
board[0][j] = '#';
k = 1;
break;
}
}
break;
}
//判斷電腦在對角線上是否會贏,又加了一個while是為了讓判斷對角線的代碼成塊,
while (0 == k)
{
if (board[0][0] == board[1][1] && board[1][1] == '#' && board[2][2] == ' ')
{
board[2][2] = '#';
k = 1;
break;
}
if (board[0][0] == board[2][2] && board[2][2] == '#' && board[1][1] == ' ')
{
board[1][1] = '#';
k = 1;
break;
}
if (board[1][1] == board[2][2] && board[1][1] == '#' && board[0][0] == ' ')
{
board[0][0] = '#';
k = 1;
break;
}
if (board[0][2] == board[1][1] && board[0][2] == '#' && board[2][0] == ' ')
{
board[2][0] = '#';
k = 1;
break;
}
if (board[0][2] == board[2][0] && board[2][0] == '#' && board[1][1] == ' ')
{
board[1][1] = '#';
k = 1;
break;
}
if (board[1][1] == board[2][0] && board[2][0] == '#' && board[0][2] == ' ')
{
board[0][2] = '#';
k = 1;
break;
}
break;
}
k = judge_player(board, row, col, k);
return k;回傳一個k==0的值表示自己下一步無法取勝
}
玩家是否能贏
??在判斷了上一步之后,電腦下一步不可能贏,那這時候來判斷玩家下一步是否能贏,如果玩家下一步能贏,那二話不說,不管三七二十一,咱攔截,如果玩家也不能贏呢,那咱的電腦就只能乖乖的走偽亂數啦,
//下面這個函式就是判斷玩家是否有機會贏,如果能贏就堵住他
char judge_player(char board[ROW][COL], int row, int col, int k)
{
int i = 0;
int j = 0;
while (0 == k)
{
//判斷玩家在橫行上是否會贏
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == '*' && board[i][2] == ' ')
{
board[i][2] = '#';
k = 1;
break;
}
if (board[i][0] == board[i][2] && board[i][0] == '*' && board[i][1] == ' ')
{
board[i][1] = '#';
k = 1;
break;
}
if (board[i][1] == board[i][2] && board[i][1] == '*' && board[i][0] == ' ')
{
board[i][0] = '#';
k = 1;
break;
}
}
if (k != 0)
break;
//判斷玩家在豎列上是否會贏
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == '*' && board[2][j] == ' ')
{
board[2][j] = '#';
k = 1;
break;
}
if (board[0][j] == board[2][j] && board[2][j] == '*' && board[1][j] == ' ')
{
board[1][j] = '#';
k = 1;
break;
}
if (board[1][j] == board[2][j] && board[2][j] == '*' && board[0][j] == ' ')
{
board[0][j] = '#';
k = 1;
break;
}
}
break;
}
//判斷玩家在對角線上是否會贏,又加了一個while是為了讓判斷對角線的代碼成塊,
while (0 == k)
{
if (board[0][0] == board[1][1] && board[1][1] == '*' && board[2][2] == ' ')
{
board[2][2] = '#';
k = 1;
break;
}
if (board[0][0] == board[2][2] && board[2][2] == '*' && board[1][1] == ' ')
{
board[1][1] = '#';
k = 1;
break;
}
if (board[1][1] == board[2][2] && board[1][1] == '*' && board[0][0] == ' ')
{
board[0][0] = '#';
k = 1;
break;
}
if (board[0][2] == board[1][1] && board[0][2] == '*' && board[2][0] == ' ')
{
board[2][0] = '#';
k = 1;
break;
}
if (board[0][2] == board[2][0] && board[2][0] == '*' && board[1][1] == ' ')
{
board[1][1] = '#';
k = 1;
break;
}
if (board[1][1] == board[2][0]&& board[2][0] == '*' && board[0][2] == ' ')
{
board[0][2] = '#';
k = 1;
break;
}
break;
}
return k;//回傳一個k==0的值,表自己下一步贏不了,也無須堵住對手,
}
新的ComputerMove函式
??電腦下棋需要加一步,獲取回傳值,如果回傳值為N,那么電腦只有乖乖的按照偽亂數來走啦,
//電腦輸入
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
int z = 0;
printf("電腦:我走過啦!!!到你啦!!!\n\n");
z = check_computer(board, row, col);
while (0 == z)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
新的game函式
??改了游戲勝利,平局和失敗的輸出文案,其余的沒動,
void menu(void)
{
printf("****************************************\n");
printf("*****1.開始游戲 0.退出游戲*****\n");
printf("****************************************\n");
}
void game(void)
{
char ret = 0;
char board[ROW][COL] = { 0 };
//初始化棋盤
InitBoard(board, ROW, COL);
//列印棋盤
DisplayBoard(board, ROW, COL);
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判斷玩家是否勝利
ret = Win(board, ROW, COL);
if (ret != 'C')
{
break;
}
//電腦下棋
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判斷電腦是否勝利
ret = Win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("恭喜你贏啦!!!哇哦,太棒了!沒幾個人能戰勝我呢!\n");
printf("\n");
}
else if (ret == '#')
{
printf("你輸了!!!emmm,不過沒關系,畢竟你是人類哇!\n");
printf("\n");
}
else
{
printf("平局!!!嗯嗯,你已經不錯了,但還要加油哦!\n");
printf("\n");
}
}
void test(void)
{
int input = 0;
do
{
menu();
printf("\n");
printf("系統提示:請選擇:>>>");
scanf("%d", &input);
printf("\n");
switch (input)
{
case 1:
game();
break;
case 0:
printf("破游戲,俺不玩了,\n");
break;
default:
printf("電腦:FBI warning 非法輸入,非法輸入,請您自覺點,\n\n電腦:乖,咱重新輸入!!!\n");
break;
}
} while (input);
}
int main(void)
{
test();
return 0;
}
完整程式
//宏定義
#define _CRT_SECURE_NO_WARNINGS 1
#define ROW 3
#define COL 3
//參考庫函式
#include<stdio.h>
#include<stdlib.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);
char Win(char board[ROW][COL], int row, int col);
char Full(char board[ROW][COL], int row, int col);
char judge_player(char board[ROW][COL], int row, int col,int k);
int check_computer(char board[ROW][COL], int row, int col);
#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 DisplayBoard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < col; i++)
{
if (i == 0)
{
printf(" %d ", i + 1);
}
else
{
printf("%d ", i + 1);
}
}
printf("\n");
for ( int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (j == 0)
{
printf("%d %c |",i+1,board[i][j]);
}
else if (j>0 && j < col - 1)
{
printf(" %c |", board[i][j]);
}
else
printf(" %c ", board[i][j]);
}
printf("\n");
if (i < row - 1)
{
for (int k = 0; k < col; k++)
{
if (k == 0)
{
printf(" ---|");
}
else if (k>0 && k < col - 1)
{
printf("---|");
}
else
{
printf("---");
}
}
}
printf("\n");
}
}
//玩家輸入
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("系統提示:請輸入您要下的坐標:>>>");
scanf("%d%d", &x, &y);
printf("\n");
//判斷xy是否合法,一個是是否溢位,一個是是否被占用
if (x > 0 && x < row + 1 && y>0 && y < col + 1)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("電腦:這我下過了,你個憨憨,\n");
printf("\n");
}
}
else
{
printf("電腦:FBI warning 非法輸入,非法輸入!!!請您自覺點\n\n電腦:乖,咱重新輸入!!!\n\n");
}
}
}
//電腦輸入
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
int z = 0;
printf("電腦:我走過啦!!!到你啦!!!\n\n");
z = check_computer(board, row, col);
while (0 == z)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
//電腦判斷自己是否會贏
int check_computer(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
int k = 0;
while (0 == k)
{
//判斷電腦橫行上是否會贏
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == '#' && board[i][2] == ' ')
{
board[i][2] = '#';
k = 1;
break;
}
if (board[i][0] == board[i][2] && board[i][0] == '#' && board[i][1] == ' ')
{
board[i][1] = '#';
k = 1;
break;
}
if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' ')
{
board[i][0] = '#';
k = 1;
break;
}
}
if (k != 0)
break;
//判斷電腦列上是否有機會贏
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == '#' && board[2][j] == ' ')
{
board[2][j] = '#';
k = 1;
break;
}
if (board[0][j] == board[2][j] && board[2][j] == '#' && board[1][j] == ' ')
{
board[1][j] = '#';
k = 1;
break;
}
if (board[1][j] == board[2][j] && board[2][j] == '#' && board[0][j] == ' ')
{
board[0][j] = '#';
k = 1;
break;
}
}
break;
}
//判斷電腦在對角線上是否會贏,又加了一個while是為了讓判斷對角線的代碼成塊,
while (0 == k)
{
if (board[0][0] == board[1][1] && board[1][1] == '#' && board[2][2] == ' ')
{
board[2][2] = '#';
k = 1;
break;
}
if (board[0][0] == board[2][2] && board[2][2] == '#' && board[1][1] == ' ')
{
board[1][1] = '#';
k = 1;
break;
}
if (board[1][1] == board[2][2] && board[1][1] == '#' && board[0][0] == ' ')
{
board[0][0] = '#';
k = 1;
break;
}
if (board[0][2] == board[1][1] && board[0][2] == '#' && board[2][0] == ' ')
{
board[2][0] = '#';
k = 1;
break;
}
if (board[0][2] == board[2][0] && board[2][0] == '#' && board[1][1] == ' ')
{
board[1][1] = '#';
k = 1;
break;
}
if (board[1][1] == board[2][0] && board[2][0] == '#' && board[0][2] == ' ')
{
board[0][2] = '#';
k = 1;
break;
}
break;
}
k = judge_player(board, row, col, k);
return k;
}
//下面這個函式就是判斷玩家是否有機會贏,如果能贏就堵住他
char judge_player(char board[ROW][COL], int row, int col, int k)
{
int i = 0;
int j = 0;
while (0 == k)
{
//判斷玩家在橫行上是否會贏
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == '*' && board[i][2] == ' ')
{
board[i][2] = '#';
k = 1;
break;
}
if (board[i][0] == board[i][2] && board[i][0] == '*' && board[i][1] == ' ')
{
board[i][1] = '#';
k = 1;
break;
}
if (board[i][1] == board[i][2] && board[i][1] == '*' && board[i][0] == ' ')
{
board[i][0] = '#';
k = 1;
break;
}
}
if (k != 0)
break;
//判斷玩家在豎列上是否會贏
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == '*' && board[2][j] == ' ')
{
board[2][j] = '#';
k = 1;
break;
}
if (board[0][j] == board[2][j] && board[2][j] == '*' && board[1][j] == ' ')
{
board[1][j] = '#';
k = 1;
break;
}
if (board[1][j] == board[2][j] && board[2][j] == '*' && board[0][j] == ' ')
{
board[0][j] = '#';
k = 1;
break;
}
}
break;
}
//判斷玩家在對角線上是否會贏,又加了一個while是為了讓判斷對角線的代碼成塊,
while (0 == k)
{
if (board[0][0] == board[1][1] && board[1][1] == '*' && board[2][2] == ' ')
{
board[2][2] = '#';
k = 1;
break;
}
if (board[0][0] == board[2][2] && board[2][2] == '*' && board[1][1] == ' ')
{
board[1][1] = '#';
k = 1;
break;
}
if (board[1][1] == board[2][2] && board[1][1] == '*' && board[0][0] == ' ')
{
board[0][0] = '#';
k = 1;
break;
}
if (board[0][2] == board[1][1] && board[0][2] == '*' && board[2][0] == ' ')
{
board[2][0] = '#';
k = 1;
break;
}
if (board[0][2] == board[2][0] && board[2][0] == '*' && board[1][1] == ' ')
{
board[1][1] = '#';
k = 1;
break;
}
if (board[1][1] == board[2][0]&& board[2][0] == '*' && board[0][2] == ' ')
{
board[0][2] = '#';
k = 1;
break;
}
break;
}
return k;
}
//判斷勝負
char Win(char board[ROW][COL], int row, int col)
{
int i = 0;
//判斷行
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')//行元素一樣且不是空格
{
return board[i][1];
}
}
//判斷列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')//列元素一樣且不是空格
{
return board[1][i];
}
}
//判斷對角線
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')//對角線元素一樣且不是空格
{
return board[1][1];
}
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
{
return board[1][1];
}
//判斷是否平局
if (1 == Full(board, ROW, COL))//平局判斷,函式在下面,已在頭檔案中宣告,位置就無所謂了
{
return 'Q';
}
return 'C';
}
//平局演算法函式
char Full(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
#include"game.h"
//游戲選單
void menu(void)
{
printf("****************************************\n");
printf("*****1.開始游戲 0.退出游戲*****\n");
printf("****************************************\n");
}
void game(void)
{
char ret = 0;
char board[ROW][COL] = { 0 };
//初始化棋盤
InitBoard(board, ROW, COL);
//列印棋盤
DisplayBoard(board, ROW, COL);
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判斷玩家是否勝利
ret = Win(board, ROW, COL);
if (ret != 'C')
{
break;
}
//電腦下棋
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判斷電腦是否勝利
ret = Win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("恭喜你贏啦!!!哇哦,太棒了!沒幾個人能戰勝我呢!\n");
printf("\n");
}
else if (ret == '#')
{
printf("你輸了!!!emmm,不過沒關系,畢竟你是人類哇!\n");
printf("\n");
}
else
{
printf("平局!!!嗯嗯,你已經不錯了,但還要加油哦!\n");
printf("\n");
}
}
void test(void)
{
int input = 0;
do
{
menu();
printf("\n");
printf("系統提示:請選擇:>>>");
scanf("%d", &input);
printf("\n");
switch (input)
{
case 1:
game();
break;
case 0:
printf("破游戲,俺不玩了,\n");
break;
default:
printf("電腦:FBI warning 非法輸入,非法輸入,請您自覺點,\n\n電腦:乖,咱重新輸入!!!\n");
break;
}
} while (input);
}
int main(void)
{
test();
return 0;
}
寫在后面
這篇博客對三子棋中電腦的演算法進行了優化,五子棋和多子棋類似就不寫在這里了,
下一篇,簡單和較難的三子棋,五子棋,多子棋小游戲的集成,
如果上面的程式或者表述有問題還請各位大佬批評指正哈,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/257182.html
標籤:其他
上一篇:攻防世界-wp-PWN-新手區-3-guess_num
下一篇:多檔案實作掃雷
