【C语言】三子棋(N子棋)判断输赢的想法

该代码实现了一个五子棋游戏的逻辑,包括初始化棋盘、玩家和电脑轮流下棋、判断获胜条件等功能。游戏使用5x5的棋盘,当有三个相同棋子连成一线时获胜。代码中优化了判断获胜的方式,从最后一个落子位置开始检查行、列和对角线的相邻棋子,减少了重复计算。
摘要由CSDN通过智能技术生成

不需要从头开始每行,每列的判断,和实际的下棋一样,从最后一个落棋的位置开始判断,以它为中心开始的行、列、斜线的去判断是否是相同的棋子相连。缺点是函数的参数会变多。

我这里用棋盘5*5的演示(判断条件还是3个棋子相连)。

假设3-3就是最后一个落棋的坐标,

那么可以从3-1做头:

        判断坐标[3][3]是否和坐标[3][1]相等,坐标[3][3]是否和坐标[3][2]相等.

从3-2做头:

        判断坐标[3][3]是否和坐标[3][2]相等,坐标[3][3]是否和坐标[3][4]相等.

 从3-3做头:

        判断坐标[3][3]是否和坐标[3][4]相等,坐标[3][3]是否和坐标[3][5]相等.

列,斜线的判断我就不举例了,下面是完整代码,代码中有具体注释,可以看game.c中最后的部分(代码就测了一两次,有问题可以提一下,电脑还是随机下棋)。

tect.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

void menu();

void game();

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
			printf("\n");
		case 1:
			game();
			break;
		case 2:
			input = 0;
			break;
		default:
			printf("错误\n");
			break;
		}

	} while (input);
	game();

	return 0;
}

void menu()
{
	printf("  1. play   \n");
	printf("  2. exit   \n");
	printf("  选择   \n");

}

void game()
{
    //创建一个记录下棋次数的变量,用于判断平局
	int count = 0;
	//创建一个保存每次下棋位置的数组
	int copy[2] = {0};
	//创建棋盘
	char board[ROW][COL] = { 0 };
	//初始化
	InitBoard(board, ROW, COL);
	//打印
	PrintBoard(board, ROW, COL);
	//玩家走
	while (1)
	{
		PlayerMove(board, ROW, COL, &count, copy);
		PrintBoard(board, ROW, COL);
		char ch = Win(board, ROW, COL, copy);
		if (ch == '*')
		{
			printf("play win\n");
			printf("\n");
			printf("\n");
			return;
		}
		if (count == ROW * COL)
		{
			printf("平局\n");
			printf("\n");
			printf("\n");
			return;
		}


		//电脑走
		ComputerMove(board, ROW, COL, &count, copy);
		PrintBoard(board, ROW, COL);
		ch = Win(board, ROW, COL, copy);
		if (ch == '#')
		{
			printf("computer win\n");
			printf("\n");
			printf("\n");
			return;
		}
		if (count == ROW * COL)
		{
			printf("平局\n");
			printf("\n");
			printf("\n");
			return;
		}

	}

}

 game.c

#include "game.h"

void InitBoard(char board[ROW][COL], int row, int col)
{
	for (int r = 0; r < row; r++)
	{
		for (int c = 0; c < col; c++)
		{
			board[r][c] = ' ';
		}

	}
}

static void _PrintBoard(char board[ROW][COL], int row, int col)
{
	printf("   ");
	for (int i = 0; i < col * 4 + 1; i++)
	{
		printf("-");
	}
	printf("\n");
}

void PrintBoard(char board[ROW][COL], int row, int col)
{
	printf("\n");
	printf("   ");
	for (int i = 1; i <= col; i++)
	{
		printf("  %d ", i);
	}
	printf("\n");
	_PrintBoard(board, row, col);
	for (int r = 0; r < row; r++)
	{
		int c = 0;
		printf(" %d ", r+1);
		for (; c < col; c++)
		{
			printf("| %c ", board[r][c]);
		}
		printf("|\n");
		_PrintBoard(board, row, col);
	}
}

void PlayerMove(char board[ROW][COL], int row, int col, int* count, int* copy)
{
	printf("\n");
	printf("玩家回合\n");
	while (1)
	{
		int r = 0;
		int c = 0;
		printf("输入坐标\n");
		scanf("%d %d", &r, &c);
		//判断坐标合法
		if (r-1 >= row || r-1 < 0 || c - 1 >= col || c - 1 < 0 || board[r - 1][c - 1] != ' ')
		{
			printf("错误\n");
			continue;
		}
		//保存下棋的位置
		copy[0] =  r - 1 ;
		copy[1] =  c - 1 ;
		board[r-1][c-1] = '*';
		(*count)++;
		return;
	}
}

void ComputerMove(char board[ROW][COL], int row, int col, int* count, int* copy)
{
	printf("\n");
	printf("电脑回合\n");
	int r, c;
	while (1)
	{
		while (1)
		{
			r = rand() % 3;
			//判断坐标合法
			if (r < row && r >= 0)
			{
				break;
			}
		}
		while (1)
		{
			c = rand() % 3;
			//判断坐标合法
			if (c < col && c >= 0)
			{
				break;
			}
		}
		//判断坐标合法
		if (board[r][c] == ' ')
		{
			//保存下棋的位置
			copy[0] = r;
			copy[1] = c;
			board[r][c] = '#';
			(*count)++;
			return;
		}
	}
}

char Win(char board[ROW][COL], int row, int col, int* copy)
{


	int wincount = 0;




	//判断列
	 
	//每列的起始位置
	int row_begin = copy[0] - (WIN - 1);
	//每列的结束位置
	int row_end = copy[0];
	//row_begin至row_end每个做头
	for (; row_begin != row_end; row_begin++)
	{
		//判断row_begin是否越界
		if (row_begin >= 0)
		{
			//row_begin
			for (int r = 0; r < WIN; r++)
			{
				if (row_begin+r >= ROW)
					break;
				if (board[row_begin+r][copy[1]] != board[copy[0]][copy[1]])
					break;
				else
					wincount++;
			}
			if (wincount == WIN)
			{
				return board[copy[0]][copy[1]];
			}
			wincount = 0;
		}
	}








	//判断行

	wincount = 0;
	//每行的起始位置
	int col_begin = copy[1] - (WIN - 1);
	//每列的结束位置
	int col_end = copy[1];

	//col_begin至col_end每个做头
	for (; col_begin != col_end; col_begin++)
	{
		//判断col_begin是否越界
		if (col_begin >= 0)
		{
			for (int c = 0; c < WIN; c++)
			{
				//判断col_begin是否越界
				if (col_begin+c >= COL)
					break;
				if (board[copy[0]][col_begin+c] != board[copy[0]][copy[1]])
					break;
				else
					wincount++;
			}
			if (wincount == WIN)
			{
				return board[copy[0]][copy[1]];
			}
			wincount = 0;
		}
	}









	//判断左斜线

	wincount = 0;
	//每列的起始位置
	row_begin = copy[0] - (WIN - 1);
	//每列的结束位置
	row_end = copy[0];
	//每行的起始位置
	col_begin = copy[1] - (WIN - 1);
	//每列的结束位置
	col_end = copy[1];

	//board[row_begin][col_begin]至board[row_end][col_end]每个做头
	for (; row_begin != row_end && col_begin != col_end; row_begin++, col_begin++)
	{
		//判断row_begin  col_begin是否越界
		if ((row_begin >= 0) && (col_begin >= 0))
		{
			for (int count = 0; count < WIN; count++)
			{
				//判断board[row_begin][col_begin]是否越界
				if (row_begin+count>=ROW || col_begin+count>=COL)
					break;
				if (board[row_begin+count][col_begin+count] != board[copy[0]][copy[1]])
					break;
				else
					wincount++;
			}
			if (wincount == WIN)
			{
				return board[copy[0]][copy[1]];
			}
			wincount = 0;
		}
	}




		
	//判断右斜线

	wincount = 0;
	//每列的起始位置
	row_begin = copy[0] - (WIN - 1);
	//每列的结束位置
	row_end = copy[0];
	//每行的起始位置
	col_begin = copy[1] + (WIN - 1);
	//每列的结束位置
	col_end = copy[1];

	//board[row_begin][col_begin]至board[row_end][col_end]每个做头
	for (; row_begin != row_end && col_begin != col_end; row_begin--, col_begin--)
	{
		//判断row_begin  col_begin是否越界
		if ((row_begin >= 0) && (col_begin < COL))
		{
			for (int count = 0; count < WIN; count++)
			{
				//判断board[row_begin][col_begin]是否越界
				if (row_begin+count>=ROW || col_begin-count<0)
					break;
				if (board[row_begin+count][col_begin-count] != board[copy[0]][copy[1]])
					break;
				else
					wincount++;
			}
			if (wincount == WIN)
			{
				return board[copy[0]][copy[1]];
			}
			wincount = 0;
		}
	}

	return;
}

game.h

#define _CRT_SECURE_NO_WARNINGS
#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 5
#define COL 5
#define WIN 3

void InitBoard(char board[ROW][COL], int row, int col);
void PrintBoard(char board[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col,int* count ,int* copy);
void ComputerMove(char board[ROW][COL], int row, int col , int* count ,int* copy);
char Win(char board[ROW][COL], int row, int col, int* copy);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值