路|【C语言/入门游戏】三子棋及改良思路

知识提要(自主编写游戏所需要的知识):
1.函数的基本实现;
2.二维数组;
好的,话不多说让我们来看今天的分享

目录

三子棋
1.初始界面实现
2.棋盘的创建及初始化棋盘
3.棋盘的打印
3.先后手的实现
4.玩家行动
5.电脑行动
6.胜负判定
7.全局展示
8.改良思路
三子棋 效果图:
路|【C语言/入门游戏】三子棋及改良思路
文章图片

1.初始界面实现 老规矩,先创建三个文件,分别为test.c(用于测试游戏以及运行游戏),game.c(用于实现游戏内函数)以及game.h(声明game.c中的函数和共同需要的数据)
先在game.h中引用你所需要的文件和必要的定义

#pragma once # define _CRT_SECURE_NO_WARNINGS#include #include #include #define ROW 3//棋盘的行 #define COL 3//棋盘的列

下面就要创建初始界面了
int main() { int input = 0; srand((unsigned int)time(NULL)); //后文有函数会用到,不理解这个函数的,可以跳转到我猜字游戏那篇文章 //这里用do while循环保证菜单至少被打开一次 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); //如果选择0,会判定为假,跳出循环,结束游戏;选择其他则不会,保证游戏可以重复游玩 return 0; }

menu():
void menu() { printf("************************\n"); printf("*******1. play******\n"); printf("*******0. exit******\n"); printf("************************\n"); }

2.棋盘的创建及初始化棋盘 首先要创建game()这个函数,然后先创建一个二维数组作为棋盘,同时我们需要将棋盘初始化。
void game() { char arr[ROW][COL]; //初始化棋盘 intialize(arr,ROW,COL); }

现在我们来写将棋盘初始化的函数intialize,这里我们用循环可以简单写成
void intialize(char board[ROW][COL] ,int row,int col) { int i = 0; for (i = 0; i < row; i++) { int j = 0; for (j = 0; j < col; j++) { board[i][j] = ' '; } }}

3.棋盘的打印 初始化棋盘后,我们需要将棋盘展示出来,打印效果如下
路|【C语言/入门游戏】三子棋及改良思路
文章图片


为了实现效果,这里我们也需要一个函数来实现,我们将其命名为print
void Print(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i < row; i++) { int j = 0; for (j = 0; j < col; j++) { printf(" %c ", board[i][j]); if (j < col - 1)//在除最后一列的其他列打印| printf("|"); } printf("\n"); //换行 if (j = col - 1)//打印---分割行 { int k = 0; if (i < row - 1)//在最后一行不打印分割行 { for (k = 0; k < col; k++) { printf("---"); if (k < col - 1) printf("|"); } } } printf("\n"); } }

只需将ROW,COL定义换成其他数就可以打印各种棋盘。如果棋盘过大,则需要标明行列号,此处暂不演示,具体实现见下一篇扫雷文章。
3.先后手的实现 为了使玩家和电脑都可以先手,我们用一个Dice的类似于骰子的函数实现
int Dice() { return rand() % 2; //返回0或1}

在game()中接收,并判定
int ret = Dice(); if (ret == 1)//返回为1,玩家先走 { Playermove(arr, ROW, COL); Computermove(arr, ROW, COL); } else//返回为0,电脑先走 {Computermove(arr, ROW, COL); Playermove(arr, ROW, COL); }

4.玩家行动 现在到了本游戏的重点,玩家行动,这里我们用o来代表玩家的棋子
玩家下棋代表用o将棋盘中的空格替代
void Playermove(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; printf("玩家走>:示例(输入:1 1)\n"); while (1)//防止输入错误以及非法占用 { printf("请输入坐标>:"); scanf("%d%d", &i, &j); if (i <= row && j <= col&&i>=1&&j>=1)//防止输入的数字超过最大访问范围 { if (board[i-1][j-1] == ' ')//如果该位置为空格,才能下 { board[i-1][j-1] = 'o'; //玩家眼中的坐标是从1开始的,而C语言中是从0开始,所以要减1 break; } else printf("该棋位已被占用,请重新输入\n"); } else { printf("输入错误,请重新输入\n"); } }

5.电脑行动 【路|【C语言/入门游戏】三子棋及改良思路】我们先不讨论如何让电脑有智商,这个放在文章结尾讨论。我们先设置一个随机的电脑
void Computermove(char board[ROW][COL], int row, int col) { printf("电脑走\n"); int x = 0; int y = 0; //人工智障 while (1) { x = rand() % ROW; y = rand() % COL; if (board[x][y] == ' ')//保证电脑也下到空格位置,不是空格就再次循环 { board[x][y] = 'x'; break; } } }

6.胜负判定 这里我们需要列举全部的游戏情况
胜利:横行三子,竖行三子,对角线三子
平局:棋盘已被占满且无胜利情况
继续:棋盘未占满且没有胜利情况
我们规定
如果玩家胜利,返回'o'
如果电脑胜利,返回'x'
如果平局,返回'E'
如果继续,返回'C
用于在test.c中判定胜负
每一方行动完后,都要判定胜负
int even(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] == ' ') return 0; } } return 1; }char win(char board[ROW][COL], int row, int col) { int i = 0; //judge row 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]; //直接返回其中的字符,方便后续判定 } //judge col 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]; } //judge dia if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') return board[1][1]; if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ') return board[1][1]; //judge even if (even(board, row, col)==1)//在上述胜利条件都没满足的情况下,才判断是否平局 return 'E'; return 'C'; }

7.全局展示 现在大体的游戏函数写得差不多了,可以将填充到game.h和test.c中了
记得要使用game.c中的函数,一定要在game.h中声明,并且引用game.h
game.h
#pragma once # define _CRT_SECURE_NO_WARNINGS#include #include #include #define ROW 3 #define COL 3void intialize(char board[ROW][COL], int row, int col); void Print(char board[ROW][COL], int row, int col); int Dice(); 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); //如果玩家胜利,返回o;如果电脑胜,返回x;平局,返回E;继续返回C

test.c
# define _CRT_SECURE_NO_WARNINGS#include "game.h"void menu() { printf("************************\n"); printf("*******1. play******\n"); printf("*******0. exit******\n"); printf("************************\n"); }void game() { char arr[ROW][COL]; //初始化棋盘 intialize(arr,ROW,COL); Print(arr,ROW,COL); int ret = Dice(); char Win = 0; if (ret == 1) { while (1) { Playermove(arr, ROW, COL); Print(arr, ROW, COL); Win = win(arr, ROW, COL); if (Win !='C') break; Computermove(arr, ROW, COL); Print(arr, ROW, COL); Win = win(arr, ROW, COL); if (Win != 'C') break; } } else { while (1) { Computermove(arr, ROW, COL); Print(arr, ROW, COL); Win = win(arr, ROW, COL); if (Win != 'C') break; Playermove(arr, ROW, COL); Print(arr, ROW, COL); Win = win(arr, ROW, COL); if (Win != 'C') break; } } if (Win == 'o') printf("恭喜,玩家胜利\n"); else if (Win == 'x') printf("电脑赢了,别灰心\n"); else if (Win == 'E') printf("平局,再来一把吧\n"); }int main() { 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"); } } while (input); return 0; }

8.改良思路
while (1) { if (board[1][1] == 'o')// 防守为上 { if (board[1][2] == 'o' && board[1][0] == ' ') { board[1][0] == 'x'; break; } else if (board[1][0] == 'o' && board[1][2] == ' ') { board[1][2] == 'x'; break; } else if (board[0][1] == 'o' && board[2][1] == ' ') { board[2][1] == 'x'; break; } else if (board[2][1] == 'o' && board[0][1] == ' ') { board[0][1] == 'x'; break; } else if (board[2][2] == 'o' && board[0][0] == ' ') { board[0][0] == 'x'; break; } else if (board[0][0] == 'o' && board[2][2] == ' ') { board[0][1] == 'x'; break; } else if (board[0][2] == 'o' && board[2][0] == ' ') { board[2][0] == 'x'; break; } else if (board[2][0] == 'o' && board[0][2] == ' ') { board[0][2] == 'x'; break; }} /*int i = 0; *///for (i = 0; i < row - 1; i++)//竖行防守 //{ // int j = 0; // for (j = 0; j < col ; j++) // { //if (board[i][j] == 'o' && board[i + 1][j] == 'o') //{ //if (i == 0 && board[i + 2][j] = ' ') //{ //board[i + 2][j] = 'x'; //} //else if (i == 1 && board[i - 1][j] = ' ') //{ //board[i - 1][j] = 'x'; //} //}// }//}if (board[1][1] == ' ')//抢中间位置 { board[1][1] == 'x'; break; } if (board[1][1] == 'x')//当有子在中间时的走法 { if ( board[1][2] == 'x'&& board[1][0] == ' ') { board[1][0] == 'x'; break; } else if (board[1][0] == 'x' && board[1][2] == ' ') { board[1][2] == 'x'; break; } else if(board[0][1] == 'x' && board[2][1] == ' ') { board[2][1] == 'x'; break; } else if (board[2][1] == 'x' && board[0][1] == ' ') { board[0][1] == 'x'; break; } else if (board[2][2] == 'x' && board[0][0] == ' ') { board[0][0] == 'x'; break; } else if (board[0][0] == 'x' && board[2][2] == ' ') { board[0][1] == 'x'; break; } else if (board[0][2] == 'x' && board[2][0] == ' ') { board[2][0] == 'x'; break; } else if (board[2][0] == 'x' && board[0][2] == ' ') { board[0][2] == 'x'; break; }}} }

上面的是一些如何提升电脑智商的代码,其中要考虑的问题比较多,而且代码执行顺序也要加以斟酌,大家可以把我这几段代码当参考,还有进攻等问题我还没有写出来,所以直接套用是不行的。

以上就是本次的分享内容了,喜欢我的分享的话,别忘了点赞加关注哟!
如果你对我的文章有任何看法,欢迎在下方评论留言或者私信我鸭!
我是白晨,我们下次分享见!!

    推荐阅读