前言
三子棋小游戏是一个运用循环结构和选择结构实现的代码量适中的程序,适合c语言的初学者在学完循环和选择结构之后尝试自己将代码写出来。编写完这个小游戏后,你会发现你的编程能力有了很大提高。
在编写小游戏时,运用了将功能函数与测试函数分开的思想,大大简化了测试函数的代码量,提高了可读性,这种将功能函数和测试函数分开的方法会在今后的学习中得到更多应用。
目录
测试文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void game() {
InitBoard();
Display();
char ret=' ';
while (IsFull() == 0) {
Gamer();
ret = CheckWin();
if (ret == '*'|| ret == '#') break;
Computer();
ret = CheckWin();
if (ret == '*' || ret == '#') break;
}
if (ret == '*') {
printf("玩家赢\n");
}
else if (ret == '#') {
printf("电脑赢\n");
}
else if (IsFull()) {
printf("平局\n");
}
}
void menu() {
printf("****************************************\n");
printf("***************1.play*******************\n");
printf("***************0.exit*******************\n");
printf("****************************************\n");
printf("please input a number:>");
}
void test() {
int input = 0;
do {
menu();
scanf("%d", &input);
switch (input) {
case 1:
game();
break;
case 0:
printf("exit!");
break;
default:
printf("wrong number!\n");
break;
}
} while (input);
}
int main() {
test();
return 0;
}
测试函数代码分析
1.利用dowhile和switch实现重复玩这一需求
2.当玩家或电脑有一方获胜时跳出循环,通过ret里的值来判断到底是谁获胜
3.当isfull不为0时,即棋盘已满时,也跳出,此时ret中的值既不是*也不是#,所以输出平局
功能函数文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
char board[ROW][COL];
void InitBoard() {
for (int r = 0; r < ROW; r++) {
for (int c = 0; c < COL; c++)
{
board[r][c] = ' ';
}
}
}
void Display() {
printf("\n");
for (int r = 0; r < ROW; r++) {
for (int c = 0; c < COL; c++)
{
if (c == 0)printf(" ");
printf(" %c ", board[r][c]);
if (c < COL - 1) printf("|");
}
printf("\n");
if (r < ROW - 1) {
for (int c = 0; c < COL; c++)
{
if (c == 0)printf(" ");
printf("---");
if (c < COL - 1) printf("|");
}
printf("\n");
}
}
printf("\n");
}
void Gamer() {
int x = 0, y = 0;
while (IsFull() == 0) {
printf("玩家请落子:>");
scanf("%d %d", &x, &y);
if (x <= 0 || x > ROW || y <= 0 || y > COL) {
printf("请输入正确的坐标!\n");
continue;
}
else if (board[x - 1][y - 1] != ' ') {
printf("这里已经有人下了qwq\n");
continue;
}
else {
board[x - 1][y - 1] = '*';
break;
}
}
Display();
}
void Computer() {
srand((unsigned int)time(NULL));
int x, y;
while (IsFull()==0) {
x = rand() % ROW;
y = rand() % COL;
if (board[x][y] == '*'|| board[x][y] == '#') {
continue;
}
else {
printf("电脑落子:>");
board[x][y] = '#';
break;
}
}
Display();
}
char CheckWin() {
char ret = ' ';
for (int r = 0; r < ROW; r++) {
if (board[r][0] == board[r][1] && board[r][2] == board[r][1])
ret = board[r][0];
}
for (int c = 0; c < COL; c++) {
if (board[0][c] == board[1][c] && board[2][c] == board[1][c]) {
ret = board[0][c];
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
ret = board[0][0];
}
if (board[2][0] == board[1][1] && board[1][1] == board[0][2]) {
ret = board[1][1];
}
return ret;
}
}
int IsFull() {
int flag = 1;
for (int r = 0; r < ROW; r++) {
for (int c = 0; c < COL; c++)
{
if (board[r][c] == ' ') flag = 0;
}
}
return flag;
}
功能函数代码分析
1.因为将棋盘的数据装在数组里,所以要首先初始化数组,即把数组置空
2.将数组格式打印在屏幕中
3.玩家和电脑分别下棋,玩家下棋利用scanf()读输入,电脑下棋利用rand生成随机值
注:玩家下棋时输入的数据从一开始,由此,在设计时需要考虑输入与for循环中值之间的关系!
4.判断玩家和电脑是否赢,或是平局
5.设置一个isfull函数判断当前棋盘(数组)是否已经装满
头文件
#pragma once
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define ROW 3
#define COL 3
void InitBoard();
void Display();
void Gamer();
void Computer();
char CheckWin();
头文件分析
1.在头文件中定义ROW和COL,便于调节棋盘大小
2.通过将函数的声明都放在头文件里。再在测试文件中包含头文件的方法,就可以实现功能函数文件和测试文件的分离