三子棋(C语言实现)
Posted fucktheperfect
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三子棋(C语言实现)相关的知识,希望对你有一定的参考价值。
三子棋
最近学习了C语言数组相关的基础知识, 学知识就是为了用嘛,使用知识也会让我们的学习过程更有趣。我们就用这些基础的知识写一个简单的三子棋小游戏,让我们与电脑对抗(当然,由于实力原因,这个电脑只能纯随机地放置棋子)实现效果如下图:
好家伙,之前我试了多少遍来故意让电脑赢,可他就是不赢,这我一写博客,想再试一次,就成功了(我只是想说我是故意输给电脑的,好面子)
代码实现
首先我们要知道,写这样一个游戏,我们会写很多行的代码,而如果这时候我们规划不得当的话,我们的代码就会变得非常乱,因此我们遵照以下规则:
- 把整个工程分为3个文件,test.c,game.c,game.h
- test.c存放main函数,用来当作程序的入口,并引用game.h头文件,即
#include"game.h"
- game.c中存放各种各样的函数,并引用game.h头文件
- game.h中存放各种函数的声明以及VS提供的头文件的包含
- 每个函数尽量只实现一个功能,这样我们的代码会更有序,更易修改
- 把棋盘的行、列定义为宏,便于修改。即:
#define R 3
#define C 3
- 玩家放置的棋子为’*’,电脑放置的棋子为’#’, 默认的格子为’ ’
- 用一个3*3的二维数组来盛放整个棋盘
主函数
int main()
{
int input = 0;//存放用户的选择
srand((unsigned int)time(NULL));//设置随机数种子,后面会用到
do//至少执行一次循环
{
menu();//打印菜单
printf("Please enter you choice(0/1):>");//要求用户输入他的选择
scanf("%d", &input);
switch (input)
{
case 1:
game();//用户输入1,进入游戏
break;
case 0:
printf("Exit.\\n");
exit(886);//用户输入0,退出程序
break;
default:
printf("Wrong!Please enter a right choice(0/1):>\\n");//处理特殊情况
break;
}
} while (input);//游戏结束后,再次进入循环
return 0;
}
菜单函数
功能就是打印菜单
void menu()
{
printf("----------------------------\\n");
printf("----- 1.play ------\\n");
printf("----- 0.exit ------\\n");
printf("----------------------------\\n");
}
游戏函数
void game()
{
char ret = 0;//用ret来判断游戏输赢,ret为'*'就代表玩家赢,为'#'就代表电脑赢,为'C'就表示继续,为'Q'就表示平局
char arr[R][C] = { 0 };//棋盘
init(arr,R,C);//初始化棋盘
show(arr,R,C);//打印棋盘
while (1)//人机循环放置棋子
{
player(arr, R, C);
ret=judge(arr,R,C);//放置一次,判断一次
if (ret != 'C')//直至ret!='C',说明游戏已结束,跳出循环
{
break;
}
computer(arr, R, C);
ret=judge(arr,R,C);
if (ret != 'C')
{
break;
}
}
//游戏已结束,判断结束的三种情况:人赢;电脑赢;平局。
if (ret == '*')
{
printf("You win!\\n");
}
else if (ret == '#')
{
printf("You lose!\\n");
}
else
{
printf("This is a draw!\\n");//draw:n.平局
}
}
初始化棋盘函数
把棋盘都初始化为空格
void init(char arr[R][C],int r,int c)
{
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
arr[i][j] = ' ';
}
}
}
打印棋盘函数
为了打印的好看,我们增加了一点别的东西
void show(char arr[R][C], int r, int c)
{
int i = 0;
for (i = 0; i < r; i++)
{
int j = 0;
for (j = 0; j < c; j++)
{
printf(" %c ", arr[i][j]);
if (j < c - 1)
printf("|");
}
printf("\\n");
if (i < r - 1)
{
for (j = 0; j < c; j++)
{
printf("---");
if (j < c - 1)
printf("|");
}
}
printf("\\n");
}
}
分析可知:这个函数需要在游戏开始时调用一次,而后在玩家或电脑放置棋子后调用一次
玩家放置棋子的函数
void player(char arr[R][C], int r, int c)
{
printf("This is your turn,and you want to place it on:>");
int row, col;
scanf("%d%d", &row, &col);
while (1)
{
if (arr[row - 1][col - 1] == ' ')//棋盘上的坐标减一才等于数组里的下标
{
arr[row - 1][col - 1] = '*';//玩家放置*
show(arr,r,c);//放置后打印一下
break;
}
else//放置的位置不是空格,说明放置的未知错误
{
printf("Wrong!Please choose again.");
}
}
}
电脑放置棋子的函数
void computer(char arr[R][C], int r, int c)
{
printf("This is the computer's turn.");
while (1)
{
int row = rand() % R;//随机数除以行数得到0~R-1之间的随机数
int col = rand() % C;//同理
if (arr[row][col] == ' ')
{
arr[row][col] = '#';//电脑放置#
printf("And computer puts it on %d %d.\\n", row + 1, col + 1);
show(arr,r,c);
break;
}
}
}
判断游戏的函数
每次玩家或电脑放置一次棋子后,我们都需要判断游戏是否已经结束
char judge(char arr[R][C],int r,int c)
{
int i = 0;
//判断一行的情况
for (i = 0; i < r; i++)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' ')
{
return arr[i][0];//返回的值即为玩家或电脑所下的字符,分别代表玩家或电脑赢
}
}
//判断一列的情况
for (i = 0; i < c; i++)
{
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
{
return arr[0][i];
}
}
//判断对角线
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[1][1] != ' ')
return arr[1][1];
if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1] != ' ')
return arr[1][1];
//判断棋盘是否已满,返回值为1时,返回'Q',代表平局
if (full(arr, r, c))
{
return 'Q';
}
return 'C';//棋盘未满,返回'C',继续游戏
}
判断棋盘是否已满的函数
int full(char arr[R][C], int r, int c)//判断棋盘是否已满,未满则返回0,继续游戏,否则返回1,平局结束游戏
{
int i = 0;
int j = 0;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
if (arr[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
完整代码
头文件:game.h
#pragma once
#define R 3
#define C 3
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
void menu();
void init(char arr[R][C],int r,int c);
void show(char arr[R][C], int r, int c);
void game();
void player(char arr[R][C], int r, int c);
void computer(char arr[R][C], int r, int c);
char judge(char arr[R][C], int r, int c);
存放函数的文件:game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void game()
{
char ret = 0;//用ret来判断游戏输赢
char arr[R][C] = { 0 };//棋盘
init(arr,R,C);//初始化棋盘
show(arr,R,C);//打印棋盘
while (1)//人机循环放置棋子
{
player(arr, R, C);
ret=judge(arr,R,C);//放置一次,判断一次
if (ret != 'C')//直至ret!='c',说明游戏已结束,跳出循环
{
break;
}
computer(arr, R, C);
ret=judge(arr,R,C);
if (ret != 'C')
{
break;
}
}
//游戏已结束,判断结束的情况:人赢;电脑赢;平局。
if (ret == '*')
{
printf("You win!\\n");
}
else if (ret == '#')
{
printf("You lose!\\n");
}
else
{
printf("This is a draw!\\n");//draw:n.平局
}
}
void player(char arr[R][C], int r, int c)
{
printf("This is your turn,and you want to place it on:>");
int row, col;
scanf("%d%d", &row, &col);
while (1)
{
if (arr[row - 1][col - 1] == ' ')//棋盘上的坐标减一才等于数组里的下标
{
arr[row - 1][col - 1] = '*';//玩家放置*
show(arr,r,c);//放置后打印一下
break;
}
else//放置的位置不是空格,说明放置的未知错误
{
printf("Wrong!Please choose again.");
}
}
}
void computer(char arr[R][C], int r, int c)
{
printf("This is the computer's turn.");
while (1)
{
int row = rand() % R;//随机数除以行数得到0~R-1之间的随机数
int col = rand() % C;//同理
if (arr[row][col] == ' ')
{
arr[row][col] = '#';//电脑放置#
printf("And computer puts it on %d %d.\\n", row + 1, col + 1);
show(arr,r,c);
break;
}
}
}
int full(char arr[R][C], int r, int c)//判断棋盘是否已满,未满则返回0,继续游戏,否则返回1,结束游戏
{
int i = 0;
int j = 0;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
if (arr[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
char judge(char arr[R][C],int r,int c)
{
int i = 0;
//判断一行的情况
for (i = 0; i < r; i++)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] 《C语言入门》三子棋C语言实现(详细版)