三子棋小程序

一.自定义头文件(game.h)

放入源文件需要用到的标准库头文件函数的声明

ROW 和COL为棋盘的行和列,三子棋嘛,肯定为3啦

#pragma once
#include<stdio.h>
#include<String.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3
void InitBoard(char board[ROW][COL], int row, int col);
void DisplayBoard(char board[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col);
void ComputerBoard(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);

二.源文件(test.c和game.c)

1.test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

void menu() {
	printf("***********************************\n");
	printf("************1.开始游戏*************\n");
	printf("************0.退出游戏*************\n");
	printf("***********************************\n");
}
void game() {
    char board[ROW][COL] = {0};
	InitBoard(board,ROW,COL);//初始化棋盘
	DisplayBoard(board, ROW, COL);//显示棋盘
	while (1) {
		PlayerMove(board, ROW, COL);//玩家输入坐标
		DisplayBoard(board, ROW, COL);//然后显示一边棋盘当前的情况
		if (IsWin(board, ROW, COL) != 'C') {//满了或者有一方赢了就break
			break;
		}
		ComputerBoard(board, ROW, COL);//人机输入坐标
		DisplayBoard(board, ROW, COL);//再显示一边棋盘当前的情况
		if (IsWin(board, ROW, COL) != 'C') {//人机输入坐标后再判断一下满没满或者双方有没有赢的,满足就break
			break;
		}
	}
	if (IsWin(board, ROW, COL) == '*') {
		printf("玩家赢\n");
		
	}
	else if (IsWin(board, ROW, COL) == '#') {
		printf("电脑玩家赢\n");
		
	}
	else if (IsWin(board, ROW, COL) == 'D') {
		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;
}

(1)void game()解释

1.先创建一个游戏面板二维数组

字符型的

char board[ROW][COL] = {0};
2.初始化棋盘
InitBoard(board,ROW,COL);
3.显示棋盘

在真正开始游戏之前肯定得先给玩家看一下棋盘滴啦

DisplayBoard(board, ROW, COL);//显示棋盘
4.while()循环

在玩家输入坐标之后

判断一下棋盘是否满了或者有一方赢了就break

同理,人机输入坐标后也是如此

(每次执行IsWin都会返回一个字符)

while (1) {
	PlayerMove(board, ROW, COL);//玩家输入坐标
	DisplayBoard(board, ROW, COL);//然后显示一边棋盘当前的情况
	if (IsWin(board, ROW, COL) != 'C') {
		break;
	}
	ComputerBoard(board, ROW, COL);//人机输入坐标
	DisplayBoard(board, ROW, COL);//再显示一边棋盘当前的情况
	if (IsWin(board, ROW, COL) != 'C') {
		break;
	}
}

注意:符号' C '说明没满并且没有一方赢

5.判赢

在while()循环出来后,肯定是有一方赢了或者满了

如果返回的符号为‘ * ’则玩家赢

如果返回的符号为‘ # ’则人机(电脑玩家)赢

如果返回的符号为‘ D ’则平局

具体可以看一下下文的IsWin函数具体实现,有注解

if (IsWin(board, ROW, COL) == '*') {
	printf("玩家赢\n");
	
}
else if (IsWin(board, ROW, COL) == '#') {
	printf("电脑玩家赢\n");
	
}
else if (IsWin(board, ROW, COL) == 'D') {
	printf("平局\n");
	
}

2.game.c

(1)初始化棋盘(InitBoard)

void InitBoard(char board[ROW][COL], int row, int col) {
	//InitBoard(board,ROW,COL);//初始化棋盘
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			board[i][j] = ' ';
		}
		
	}
	/*或者直接写这一行代码也可以memset(&board[0][0], ' ', row * col * sizeof(board[0][0]));*/
}

(2)显示棋盘(DisplayBoard)

void DisplayBoard(char board[ROW][COL], int row, int col) {
	//DisplayBoard(board, ROW, COL);//显示棋盘
	for (int i = 0; i < row; i++) {
		if (i < 2) {
			printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
			printf("---|---|---\n");
		}
		else {
			printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
		}
	}

}

效果如图:

(3)玩家输入坐标(PlayerMove)

玩家的棋子是' * '号

void PlayerMove(char board[ROW][COL], int row, int col) {
	//PlayerMove(board, ROW, COL);//玩家输入坐标
	int x, y;
	printf("玩家下棋:>\n");
	printf("请输入棋子的坐标:");
	scanf("%d %d", &x, &y);
	while (1) {
		if (x <= 0 && x >= 4 && y <= 0 && y >= 4) {
			printf("坐标非法,请重新输入\n");
		}
		else if (board[x - 1][y - 1] == ' ') {
			board[x - 1][y - 1] = '*';
			break;
		}
		else {
			printf("坐标已经被占用,请重新输入坐标\n");
			break;
		}
	}
}

效果如图:

(4)人机下棋(ComputerBoard)

人机的棋子是' # '号

void ComputerBoard(char board[ROW][COL], int row, int col) {
	//ComputerBoard(board, ROW, COL);//人机输入坐标
	//DisplayBoard(board, ROW, COL);//然后显示一边棋盘当前的情况
	printf("电脑下棋:>\n");
	int x, y;
	while (1) {
		x = rand() % row;//模上一个3之后得到的数的范围肯定为0~2
		y = rand() % col;
		if (board[x][y] == ' ') {
			board[x][y] = '#';
			break;
		}
	}
}

效果如图:

可以看到我们在输入坐标后紧跟着人机也输入了坐标

(5)判定双方是否赢了(IsWin)

char IsWin(char board[ROW][COL], int row, int col) {
	//IsWin(board, ROW, COL) 判定双方是否赢了

    //判断行是否相等(注意不为空),相等的话就返回其对应的棋子,再下定论谁赢了
	for (int i = 0; i < row; i++) {
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&&board[i][2]!=' ') {
			return board[i][0];//返回
		}
    }

    //判断列是否相等(注意不为空),相等的话就返回其对应的棋子,再下定论谁赢了
	for (int j = 0; j < col; j++) {
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[2][j] != ' ') {
			return board[0][j];//返回
		}
	}

    //判断两对角线是否相等(注意不为空),相等的话就返回其对应的棋子,再下定论谁赢了
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' ') {
		return board[0][0];//返回
    }
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ') {
		return board[0][2];//返回
	}

    
    //判断是否满了,返回不同的字符执行不同的效果
	if (IsFull(board, ROW, COL)) {
		return 'D';//返回
	}
	else {
		return 'C';//返回
	}
}

大致效果:

(6)判满(对应(5)中的函数IsFull())

注意该函数写在IsWin()函数的上边,否则加上声明

int IsFull(char board[ROW][COL], int row, int col) {
	//IsFull(board, ROW, COL)判满
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			if (board[i][j] == ' ') {
				return 0;//返回0说明没满,if(0)相当于false
			}
		}
	}
	return 1;//相当于true
}

一键三连哦,感谢大家的阅读!

  • 14
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值