三子棋游戏
目录
基本功能
代码编写思路
游戏思路和逻辑
三子棋游戏首先要实现棋盘的打印,然后读取玩家落子坐标,将玩家的坐标打印在棋盘上。
然后用随机函数实践电脑的下棋。
在每一步玩家和电脑下完棋后都要使用判断输赢的函数判断是否有一方赢得游戏,如果棋盘下满了未有一方赢得游戏则平局。
代码的实现
三子棋.c
菜单函数
void menu() {
printf("********************************\n");
printf("**** 0.exit 1.play****\n");
printf("********************************\n");
}
当用户输入1时开始游戏
当用户输入0时游戏结束
main主函数
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
switch (input) {
case 1:
play();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入无效请重新输入\n");
break;
}
} while (input);
return 0;
}
首先使用do-while循环将menu函数打印出来
然后使用swith语句对用户输入的选择进行判断是否进入游戏。
input变量作为用户输入的变量,当input=0时会退出while循环
当input为1时则进入play函数。
play函数
void play() {
char board[ROW][COL] = { 0 };
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘
display(board, ROW, COL);
//下棋
char ret = 0;
while (1) {
//玩家下棋
playermove(board,ROW,COL);
display(board, ROW, COL);
// 判断输赢
ret = iswin(board, ROW, COL);
if (ret != 'C')break;
//电脑下棋
computermove(board, ROW, COL);
display(board, ROW, COL);
//判断输赢
ret = iswin(board, ROW, COL);
if (ret != 'C')break;
}
if (ret == '*')printf("玩家赢\n");
else if (ret == '#')printf("电脑赢\n");
else printf("平局\n");
}
play函数作为游戏运行的主要函数,游戏棋盘的打印,玩家下棋的各个函数都依托这个函数来实现。
- 首先先将棋盘初始化,棋盘我们通过二维数组的形式来进行创建。
- 然后用InitBoard函数来初始化棋盘目的是让二维数组中的每一位都是空格,方便接下来的输入。
- 我们需要考虑下棋是需要多次进行的所以需要用while函数来进行多此循环。
- 在循环内部我们需要先让玩家下棋然后判断输赢
- 再让电脑下棋再判断输赢
- 在循环结束后打印是哪一方赢
代码
#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void play() {
char board[ROW][COL] = { 0 };
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘
display(board, ROW, COL);
//下棋
char ret = 0;
while (1) {
//玩家下棋
playermove(board,ROW,COL);
display(board, ROW, COL);
// 判断输赢
ret = iswin(board, ROW, COL);
if (ret != 'C')break;
//电脑下棋
computermove(board, ROW, COL);
display(board, ROW, COL);
//判断输赢
ret = iswin(board, ROW, COL);
if (ret != 'C')break;
}
if (ret == '*')printf("玩家赢\n");
else if (ret == '#')printf("电脑赢\n");
else printf("平局\n");
}
void menu() {
printf("********************************\n");
printf("**** 0.exit 1.play****\n");
printf("********************************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
switch (input) {
case 1:
play();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入无效请重新输入\n");
break;
}
} while (input);
return 0;
}
game.c
game.c主要进行函数功能的实现
初始化棋盘函数
遍历二维数组将棋盘初始化为空格
void InitBoard(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] = ' ';
}
}
}
打印棋盘函数
- 棋盘的本质就是二维数组
- 在打印数据的过程中用printf函数插入棋盘各个元素间的间隔符
- 首先打印数据
- 然后打印行间隔符
- 后打印列间隔符
特别注意在打印间隔符时
if (j < col - 1)
printf("|");
使用这串代码将最后的间隔符不打印
void display(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 (i < row - 1) {
for (j = 0; j < col; j++) {
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
玩家下棋函数
- 因为玩家下棋有可能下错子,也有可能下的坐标已经有棋子了,所以使用while函数在下子错误时来进行重新下子。
- 在玩家输入落子坐标后首先我们要先判断输入的坐标是否合法
- 再判断这个坐标是否为空格,只有这些条件满足才可以落子
void playermove(char board[ROW][COL], int row, int col) {
int a = 0, b = 0;
while (1) {
printf("请选择棋子落点:>");
scanf("%d %d",&a,&b);
if (a >= 1 && a <= row && b >= 1 && b <= col) {
if (board[a - 1][b - 1] == ' ') {
board[a - 1][b - 1] = '*';
break;
}
else//不能落子
{
printf("坐标被占用,不能落子,请重新输入坐标\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
电脑随机下棋
- 这个函数中使用了rand随机函数来生成一个随机数,然后通过取row,col的模来保证随机数的值在棋盘范围之内。
- 再通过判断坐标是否合法来下子。
代码
void computermove(char board[ROW][COL], int row, int col) {
int x = 0, y = 0;
printf("电脑下棋\n");
while (1) {
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ') {
board[x][y] = '#';
break;
}
}
}
判断输赢函数和判断棋盘是否下满
- 三子棋赢的条件为三个连在一起的棋子是一样的。
- 我们通过for语句来遍历行和列的各个元素是否一样,若有一方一样则输出那一方代表的符号。
- 通过if语句来判断对角线上的元素是否一样
- 再通过isfull函数来判断棋盘是否下满,若下满则返回Q
- 若以上情况都没有则返回C来表示继续
代码
int isfull(char board[ROW][COL], int row, int col) {
int f = 1;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
char iswin(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][2] == board[i][1] && board[i][0] != ' ') {
return board[i][0];
}
}
//判断列
for (i = 0; i < row; i++) {
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ') {
return board[0][i];
}
}
//判断对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
return board[1][1];
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
return board[1][1];
//平局
if (isfull(board, row, col) == 1) {
return 'Q';
}
//继续
return 'C';
}
完整代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//初始化为空格棋盘
void InitBoard(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] = ' ';
}
}
}
//打印棋盘
void display(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 (i < row - 1) {
for (j = 0; j < col; j++) {
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
void playermove(char board[ROW][COL], int row, int col) {
int a = 0, b = 0;
while (1) {
printf("请选择棋子落点:>");
scanf("%d %d",&a,&b);
if (a >= 1 && a <= row && b >= 1 && b <= col) {
if (board[a - 1][b - 1] == ' ') {
board[a - 1][b - 1] = '*';
break;
}
else//不能落子
{
printf("坐标被占用,不能落子,请重新输入坐标\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
//电脑随机下棋
void computermove(char board[ROW][COL], int row, int col) {
int x = 0, y = 0;
printf("电脑下棋\n");
while (1) {
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ') {
board[x][y] = '#';
break;
}
}
}
int isfull(char board[ROW][COL], int row, int col) {
int f = 1;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
char iswin(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][2] == board[i][1] && board[i][0] != ' ') {
return board[i][0];
}
}
//判断列
for (i = 0; i < row; i++) {
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ') {
return board[0][i];
}
}
//判断对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
return board[1][1];
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
return board[1][1];
//平局
if (isfull(board, row, col) == 1) {
return 'Q';
}
//继续
return 'C';
}
game.h
头文件主要用来声明
代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
void InitBoard(char board[ROW][COL],int row,int rol);
void display(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);