C语言三子棋Tick-Tck-Toe代码实现
Posted SuchABigBug
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言三子棋Tick-Tck-Toe代码实现相关的知识,希望对你有一定的参考价值。
三子棋游戏大家应该都玩过,游戏规则不做介绍,代码实现之前先一起过一遍思路!
1. 思维导图
2. 设计思路
结合上图,我们可以拆分为三个文件进行编写:
-
test.c文件用于测试游戏的逻辑
do…while函数,打印菜单并进行玩家输入判断
如果玩家输入1,调用game函数
如果玩家输入0, 直接break,跳出循环
如果玩家输入其他值,直接break,跳出循环这里我们具体说一说game() function的逻辑,首先要对棋盘进行初始化,具体函数实现我们在game.c中会讲到,然后把初始化好的棋盘进行打印显示。其次无论是玩家还是电脑下的每一步棋,都需要对其状态进行检查:
- 玩家回合,下完一步棋后对棋盘进行打印
- 判断字符是否返回‘C’,否则游戏继续
- 电脑回合,下完一步棋后对棋盘进行打印
- 判断是否返回‘C’,否则游戏继续
- 如果不是字符‘C’
- 返回字符‘X’,表明玩家赢了
- 返回字符’O’,表面电脑赢了
- 返回字符’Q’,棋盘已满,平局
-
game.c 用于相关函数实现
- 函数initBoard(),初始化棋盘的值都为空
- 函数DisplayBoard(),为了ROW和COL大小更通用
- 定义row行,row-1行不进行打印
- 定义col列,同理col-1列不进行打印,每行的内容先把棋盘的空值放进去后打印符号
|
,换行后对下边框进行打印---|
,注意判断如果是col-1,符号|
不进行打印。 - 棋盘展示好后,玩家开始进行下棋,结合用户习惯我们取值范围是在1~3之间,超过则表示非法越界或者棋盘的值不为空
- 函数ComputerMove(),这里电脑下棋的标准为:只判断棋盘里的值是否为空
- 函数isFull(),判断棋盘的是否已满,全满返回1,否则返回0
- 函数hasWinner(),判断是否有赢家:
- 对棋盘的每行进行判断是否值都相等且不为空
- 对棋盘的每列进行判断是否值都相等且不为空
- 对角的值判断是否都相等且不为空
-
game.h 相关函数声明,引入必要头文件及各文件需要的函数进行声明,并初始化行和列是多大
3. 代码实现
test.c
#include "game.h"
void menu(){
printf("****************************************\\n");
printf("************* 0. Exit ***************\\n");
printf("************* 1. Play ***************\\n");
printf("****************************************\\n");
}
void game(){
char board[ROW][COL];
//init board
initBoard(board, ROW, COL);
//Show board
DisplayBoard(board, ROW, COL);
/*
游戏状态检查:
1. 玩家胜利, 返回X
2. 电脑胜利, 返回O
3. 平局, 返回Q
4. 游戏继续, 返回C
*/
char ret = 0; //get game status
while(1)
{
//Player turn
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = hasWinner(board, ROW, COL);
if(ret != 'C')
break;
//Computer turn
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//Check whether got winner
ret = hasWinner(board, ROW, COL);
if(ret != 'C')
break;
}
if(ret == 'X'){
printf("Player winned \\n");
}else if(ret == 'O'){
printf("Computer winned \\n");
}else{
printf("Play Even \\n");
}
DisplayBoard(board, ROW, COL);
}
int main(){
int input=0;
srand((unsigned int)time(NULL));
do{
menu();
printf("Please Choose:> ");
scanf("%d", &input);
switch (input)
{
case 0:
printf("Exit Game\\n");
break;
case 1:
game();
printf("Playing Game\\n");
break;
default:
printf("Choose wrong, Please retry\\n");
break;
}
}while(input);
return 0;
}
game.h
#pragma once
//Head include
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3
//Declare function
void initBoard(char board[ROW][COL], int row, int col);
//print move
void DisplayBoard(char board[ROW][COL],int row,int col);
//Player‘s turn
void PlayerMove(char board[][COL], int row, int col);
//Computer's turn
void ComputerMove(char board[][COL], int row, int col);
//Does board has winner yet?
char hasWinner(char board[][COL], int row, int col);
game.c
#include "game.h"
void initBoard(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){
board[i][j] = ' '; //Init board to empty
}
}
}
void DisplayBoard(char board[ROW][COL], int row, int col){
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
printf(" %c ",board[i][j]);
if(j<col-1)
printf("|");
}
printf("\\n");
if(i<row-1)
// printf("---|---|---\\n");
for(int j=0; j<col; j++){
printf("---");
if(j<col-1)
printf("|");
}
printf("\\n");
}
}
void PlayerMove(char board[][COL], int row, int col){
int x=0;
int y=0;
while(1){
printf("Player's Turn :> \\n");
printf("Please input coordinate: >");
scanf("%d %d", &x, &y);
//Check coordinate validation
if( x>=1 && x<=row && y>=1 && y<=col ){
//Check if input x,y coordinates is valid
if(board[x-1][y-1] != ' ' ){
printf("x,y coordinate is not empty, Please Retry");
}else{
board[x-1][y-1] = 'X';
break;
}
}else{
printf("Invalid coordinate, Please Retry");
}
}
}
void ComputerMove(char board[][COL], int row, int col){
printf("Computer's Turn :? \\n");
while(1){
int x = rand()%row;
int y = rand()%col;
if(board[x][y] == ' '){
board[x][y] = 'O';
break;
}
}
}
//Check Board status below:
int isFull(char board[][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; //board not full yet~
}
}
}
return 1;
}
char hasWinner(char board[][COL], int row, int col){
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
if(board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' '){
return board[i][1];
}
}
}
//Check three col
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
if(board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ' ){
return board[1][i];
}
}
}
//check if it's diagonal
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];
}
//check if board it's full
int ret = isFull(board, row, col);
//1 indicates play even
if(ret == 1){
return 'Q';
}
return 'C';
}
为了提高可读性,我们创建了game.h,因此test.c和game.c只需要#include "game.h"
即可
如果文章对你有帮助,老铁支持一波,Thank You~ 😃
以上是关于C语言三子棋Tick-Tck-Toe代码实现的主要内容,如果未能解决你的问题,请参考以下文章