五子棋项目

五子棋

  • 思路
    • 元素
    • 棋盘
    • 判断输赢
  • 代码
    • 头文件
      • chess.h
    • 源文件
      • chessdate.cpp
      • main.cpp

思路

元素

五子棋元素为黑白两种棋子和棋盘,为此设置棋盘结构体和枚举类型设置棋子。

棋盘

以二维数组的形式设置,黑棋为1,白棋为-1.初始值设置为0。判断点击位置是否有效判断无效位置——如果点击位置不在方格处无效,点击位置所在位置有棋子则点击无效。点击位置如果点击到方格中,则鼠标点击位置的像素举例该方格四个角(落子位置)最近的位置放置棋子。

判断输赢

如果黑棋或白棋中一方五子连成一线则游戏结束,如何判断五子连成一线——以横向为例,以落子处为起点先向左开始遍历,碰到方格纸外或碰到棋子与所下棋子不一样停止,遍历一颗棋子计数器+1,然后向右遍历,如果遍历完计数器大于5等于则游戏结束,如果小于5则换另一方落子。

代码

头文件

chess.h

#pragma once
#include 
#include 
#include 
//棋盘格子 行列数
#define BOARD_SIZE 20
#define BOARD_LENGTH  700

//棋盘距离左边距离  
#define M_X 90  

//棋盘距离上边界距离
#define M_Y 140

//棋盘小格子 边长(正方形)   棋子大小
#define CHESS_SIZE  25.7
//鼠标点击  模糊距离上限 
#define POS_OFFSET  CHESS_SIZE * 0.4
typedef enum CHESS_TYPE {
	CHESS_WHITE = -1,
	CHESS_BLACK = 1
}chess_kind;

typedef struct ChessBoard {
	int chessborad[BOARD_SIZE][BOARD_SIZE]; //-1  0  1
	//bool playflag;  // 白棋false   黑棋true   
}ChessBoard;

void initchessboard(ChessBoard* pboard);//初始化棋盘
int Man_Go(int xPos, int yPos);//黑棋下棋
bool ClickBoard(MOUSEMSG msg, int* xPPos, int* yPPos);//鼠标点击位置是否在有效位置,如果有效得到鼠标点击所在数组下标
bool CheckOver(int xPos, int yPos, chess_kind kind);//是否连成五子
void init();//初始化
int AI_GO(int xPos, int yPos);//白棋下棋

源文件

chessdate.cpp

#include "chess.h"
#include "string.h"

void initchessboard(ChessBoard* pboard) {
	if (!pboard)  //if(pboard == NULL)   return;
		return;
	memset(pboard->chessborad, 0, sizeof(pboard->chessborad));
}
//#define BOARD_LENGTH  800
ChessBoard board;

int  Man_Go(int xPos, int yPos) { //xPos  yPos  有效点的像素
	//黑棋放图片  putimage()
	if (board.chessborad[xPos][yPos] == 0) {
		board.chessborad[xPos][yPos] = CHESS_BLACK;
		IMAGE img;
		loadimage(&img, "黑棋子.jpg", CHESS_SIZE, CHESS_SIZE);
		putimage(yPos * CHESS_SIZE + M_X - (CHESS_SIZE / 2), xPos * CHESS_SIZE + M_Y - (CHESS_SIZE / 2), &img);
		return 1;
	}
	return -1;
}
int AI_GO(int xPos, int yPos) {
	//白棋图片
	if (board.chessborad[xPos][yPos] == 0) {
		board.chessborad[xPos][yPos] = CHESS_WHITE;
		IMAGE img;
		loadimage(&img, "白棋子.jpg", CHESS_SIZE, CHESS_SIZE);
		putimage(yPos * CHESS_SIZE + M_X - (CHESS_SIZE / 2), xPos * CHESS_SIZE + M_Y - (CHESS_SIZE / 2), &img);
		return  1;
	}
	return -1;
}
//是否是有效点击位置,xPPos -> 二维数组行下标     yPPos  ->  二维数组的列下标
bool ClickBoard(MOUSEMSG msg, int* xPos, int* yPos) {
	if (msg.x > M_X && msg.y > M_Y&&msg.x<(BOARD_LENGTH-M_X)&&msg.y<(BOARD_LENGTH - 70)) {
		int x = msg.x, y = msg.y;// 获取鼠标点击的位置像素

		int row = (y / CHESS_SIZE - M_Y / CHESS_SIZE);
		int col = (x / CHESS_SIZE - M_X / CHESS_SIZE);
		if (((y - (M_Y + row * CHESS_SIZE)) > (CHESS_SIZE / 2)) &&
			((x - (M_X + col * CHESS_SIZE)) > (CHESS_SIZE / 2))) {
			*xPos = row + 1;
			*yPos = col + 1;

		}
		else
			if (((y - (M_Y + row * CHESS_SIZE)) < (CHESS_SIZE / 2)) &&
				((x - (M_X + col * CHESS_SIZE)) < (CHESS_SIZE / 2))) {
				*xPos = row;
				*yPos = col;

			}
			else
				if (((y - (M_Y + row * CHESS_SIZE)) > (CHESS_SIZE / 2)) &&
					((x - (M_X + col * CHESS_SIZE)) < (CHESS_SIZE / 2))) {
					*xPos = row + 1;
					*yPos = col;

				}
				else
					if (((y - (M_Y + row * CHESS_SIZE)) < (CHESS_SIZE / 2)) &&
						((x - (M_X + col * CHESS_SIZE)) > (CHESS_SIZE / 2))) {
						*xPos = row;
						*yPos = col + 1;
					}
			return true; 
		

	}
	else return false;
}

bool CheckOver(int xPos, int yPos, chess_kind kind) {
	int count = 0;
	//横向 ---x,y----    
	//横向左边
	for (int i = xPos, j = yPos; j >= 0 && board.chessborad[i][--j] == kind; ) {
		count++;
	}
	//横向右边
	for (int i = xPos, j = yPos; j < BOARD_SIZE && board.chessborad[i][++j] == kind; ) {
		count++;

	}	
	if (count >= 4) {	
		return true;
	
	}

	//正斜向  /   斜上
	count = 0;
	for (int i = xPos, j = yPos; i >= 0 && j < BOARD_SIZE && board.chessborad[--i][++j] == kind;) {
		count++;
	}
	//斜下
	for (int i = xPos, j = yPos; j >= 0 && i < BOARD_SIZE && board.chessborad[++i][--j] == kind;) {
		count++;
	}
	if (count >= 4) {
		return true;
	}
	count = 0;
	//纵向
	//向上
	for (int i = xPos, j = yPos; i >= 0 && board.chessborad[--i][j] == kind; ) {
		count++;
	}
	//向下
	for (int i = xPos, j = yPos; i < BOARD_SIZE && board.chessborad[++i][j] == kind; ) {
		count++;
	}
	if (count >= 4) {
		return true;
	}
	//反斜方向
	count = 0;
	//斜上
	for (int i = xPos, j = yPos; i >= 0 && j >= 0 && board.chessborad[--i][--j] == kind;) {
		count++;
	}
	//斜下
	for (int i = xPos, j = yPos; j < BOARD_SIZE && i < BOARD_SIZE && board.chessborad[++i][++j] == kind;) {
		count++;
	}
	if (count >= 4) {
		return true;
	}
	return false;

}

void init() {  // 展示初始界面  鼠标左键点击   播放音乐& 界面棋盘
	initgraph(BOARD_LENGTH, BOARD_LENGTH, SHOWCONSOLE);
	IMAGE image1;
	loadimage(&image1, "初始界面.jpg", BOARD_LENGTH, BOARD_LENGTH, true);
	putimage(0, 0, &image1);
	while (1) {
		MOUSEMSG msg = GetMouseMsg();
		if (msg.uMsg == WM_LBUTTONDOWN) { //左键点击开始播放音乐,切换界面
			mciSendString("open 背景音乐.mp3 alias music", 0, 0, 0);
			mciSendString("play music repeat", 0, 0, 0);
			IMAGE image2;
			loadimage(&image2, "棋盘.jpg", BOARD_LENGTH, BOARD_LENGTH, true);
			putimage(0, 0, &image2);
			break;
		}
	}
}

main.cpp

#include 
#include 
#include 
#include "chess.h"
#pragma comment(lib,"winmm.lib")
void start() {
	MOUSEMSG msg; //监听鼠标事件
	int xPos, yPos; //记录棋子即将放的位置
	init(); //初始化主界面
	bool flag = false; //交替黑白

	//监听鼠标消息,左键点击下棋,黑棋和白棋交叉进行
	while (1) {
		msg = GetMouseMsg(); //获取鼠标消息
		//ClickBoard-> 判断点击位置是否是有效位置,是,需要在有效位置下棋子
		//(msg,&xPos,&yPos)  第二个参数和第三个参数  需要吧棋子所下位置坐标带出来
		if (msg.uMsg == WM_LBUTTONDOWN && ClickBoard(msg, &xPos, &yPos)) {
			if (flag == false) {
				if (Man_Go(xPos, yPos) == 1) {  //先下黑,再下白
					if (CheckOver(xPos, yPos, CHESS_BLACK)) { //棋子成功连城5子
						//提示是否继续新游戏--> MessageBox
						//是:start();
						mciSendString("close music", 0, 0, 0);
						if (MessageBox(0, "黑棋胜利,是否开始新游戏", "五子棋", MB_OKCANCEL) ==IDCANCEL) {
						        exit(0);
						}
						else {
								start();
						}
					}
					else {
						flag = true;
					}
				}
			}
			else {
				if (AI_GO(xPos, yPos) == 1) {

				  if (CheckOver(xPos, yPos, CHESS_WHITE)) { //棋子连城5子
					  mciSendString("close music", 0, 0, 0);
				  //提示信息
					  if (MessageBox(0, "白棋胜利,是否开始新游戏", "五子棋", MB_OKCANCEL) == IDCANCEL) {
						   exit(0);
					  }
					  else {
						 start();
					  }
				  }
				flag = false;
			    }
			}
		}
	}
}

int main() {
	start();
	system("pause");
	closegraph();
	return 0;
}

你可能感兴趣的:(项目,c++)