common.h
#pragma once
#include <graphics.h>
#include <iostream>
#include <string>
#include <map>
#include<array>
#include <list>
#include <thread>
#include <vector>
#include <ctime>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")
using namespace std;
res.h
#pragma once
#include "common.h"
class Res
{
private:
Res();
public:
static int WIDTH(string name);
static int HEIGHT(string name);
static Res* GetInstance();
static void Draw_IMG(int x, int y, string name); //图片绘制
static void DrawIMG(int x, int y, string name, int preIndex);
~Res();
public:
static map<string, IMAGE*> img; //图片
static int ROW; //行|列
static int COL;
};
res.cpp
#include "res.h"
map<string, IMAGE*> Res::img; //图片
int Res::ROW = 4; //行|列
int Res::COL = 4;
/*———————————————————————————————————————————
加载 和 初始化 图片相关内容
图片分为蓝方和红方
鼠:1 9
猫:2 10
狗:3 11
狼:4 12
豹:5 13
虎:6 14
狮:7 15
象:8 16
路面:0
————————————————————————————————————————————*/
Res::Res()
{
//背景 蓝队 红队
string BackGround = "./res/background.png";
//卡片
string Card = "./res/Card.png";
//象
string Elephant[2] = {"./res/BElephant.png","./res/RElephant.png"};
//狮
string Lion[2] = { "./res/BLion.png","./res/RLion.png" };
//虎
string Tiger[2] = { "./res/BTiger.png","./res/RTiger.png" };
//豹
string Leopard[2] = { "./res/BLeopard.png","./res/RLeopard.png" };
//狼
string Wolf[2] = { "./res/BWolf.png","./res/RWolf.png" };
//狗
string Dog[2] = { "./res/BDog.png","./res/RDog.png" };
//猫
string Cat[2] = { "./res/BCat.png","./res/RCat.png" };
//鼠
string Mouse[2] = { "./res/BMouse.png","./res/RMouse.png" };
//岩浆
string Fire = "./res/Fire.png";
//路面
string Road = "./res/Road.png";
img["背景"] = new IMAGE;
img["卡片"] = new IMAGE;
img["岩浆"] = new IMAGE;
img["路面"] = new IMAGE;
img["象"] = new IMAGE[2];
img["狮"] = new IMAGE[2];
img["虎"] = new IMAGE[2];
img["豹"] = new IMAGE[2];
img["狼"] = new IMAGE[2];
img["狗"] = new IMAGE[2];
img["猫"] = new IMAGE[2];
img["鼠"] = new IMAGE[2];
loadimage(img["背景"], BackGround.c_str());
loadimage(img["卡片"], Card.c_str());
loadimage(img["岩浆"], Fire.c_str(),90,108);
loadimage(img["路面"], Road.c_str(),90,108);
for (int i = 0; i < 2; i++)
{
loadimage(img["象"] + i, Elephant[i].data(), 90, 108);
loadimage(img["狮"] + i, Lion[i].data(), 90, 108);
loadimage(img["虎"] + i, Tiger[i].data(), 90, 108);
loadimage(img["豹"] + i, Leopard[i].data(), 90, 108);
loadimage(img["狼"] + i, Wolf[i].data(), 90, 108);
loadimage(img["狗"] + i, Dog[i].data(), 90, 108);
loadimage(img["猫"] + i, Cat[i].data(), 90, 108);
loadimage(img["鼠"] + i, Mouse[i].data(), 90, 108);
}
}
int Res::WIDTH(string name)
{
return GetInstance()->img[name]->getwidth();
}
int Res::HEIGHT(string name)
{
return GetInstance()->img[name]->getheight();
}
Res* Res::GetInstance()
{
static Res* res = new Res;
return res;
}
void Res::Draw_IMG(int x, int y, string name)
{
putimage(x, y, GetInstance()->img[name]);
}
void Res::DrawIMG(int x, int y, string name, int preIndex)
{
putimage(x, y, GetInstance()->img[name] + preIndex);
}
Res::~Res()
{
delete img["背景"];
delete img["卡片"];
delete img["岩浆"];
delete img["路面"];
delete[]img["象"];
delete[]img["狮"];
delete[]img["虎"];
delete[]img["豹"];
delete[]img["狼"];
delete[]img["狗"];
delete[]img["猫"];
delete[]img["鼠"];
}
data.h
#pragma once
#include"common.h"
//根据鼠标消息,做数据的改变
class Data
{
public:
void Set();
void changeValue(int i, int j, int value);
void constValue(int i, int j, int value);
array<array<int, 4>, 4>& getMap(); //在外面画图要访问数据,提供外部访问接口
protected:
array <array< int, 4 >, 4 > map = { 0 };
};
data.cpp
#include "data.h"
#include "res.h" //用到资源
#include"common.h"
void Data::Set()
{
srand((unsigned)time(NULL));
int i = 1;
for (int a = 0; a < Res::ROW; a++)
{
for (int b = 0; b < Res::COL; b++)
{
map[a][b] = i;
i++;
}
}
for (int a = 0; a < Res::ROW; a++)
{
for (int b = 0; b < Res::COL; b++)
{
int i = rand() % 4;
int j = rand() % 4;
int t = map[i][j];
map[i][j] = map[a][b];
map[a][b] = t;
}
}
//加密格子 遍历每一个元素,对每一个元素加一个数处理,让它与原来不同,就不会输出原来对应的图片
for (int j = 0; j < Res::ROW; j++)
{
for (int k = 0; k < Res::COL; k++)
{
//++map[r][c];
changeValue(j, k, 20); //所有的都需要加密
}
}
}
void Data::changeValue(int i, int j, int value)
{
map[i][j] += value;
}
void Data::constValue(int i, int j, int value)
{
map[i][j] = value;
}
array<array<int, 4>, 4>& Data::getMap()
{
// TODO: 在此处插入 return 语句
return map;
}
DrawImg.h
#pragma once
#include"common.h"
#include"data.h"
class Data;
class Draw
{
public:
Draw();
void Game_Draw(); //根据数据画图片|数据的处理封装在Game中
Data* getData() { return pData; }
void showData();
protected:
Data* pData; //游戏需要用到数据,包含数据的指针
};
DrawImg.cpp
#include "DrawImg.h"
#include"res.h"
#include"data.h"
#include "button.h"
Draw::Draw():pData(new Data)
{
pData->Set();
initgraph(Res::WIDTH("背景"), Res::HEIGHT("背景"), EW_SHOWCONSOLE);
Res::Draw_IMG(0, 0, "背景");
}
void Draw::showData()
{
for (int i = 0; i < Res::ROW; i++)
{
for (int k = 0; k < Res::COL; k++)
{
cout << pData->getMap()[i][k] << "\t";
}
cout << endl;
}
cout << endl;
}
void Draw::Game_Draw()
{
for (int i = 0; i < Res::ROW; i++)
{
for (int k = 0; k < Res::COL; k++)
{
//前面间距28 水平间距42 上面间距65 垂直间距43
if (pData->getMap()[i][k] >= 1 && pData->getMap()[i][k] <= 16) //范围[1+20,16+20]
{
switch (pData->getMap()[i][k])
{
case 1:
Res::DrawIMG(CardX(k), CardY(i), "鼠", 0);
break;
case 2:
Res::DrawIMG(CardX(k), CardY(i), "猫", 0);
break;
case 3:
Res::DrawIMG(CardX(k), CardY(i), "狗", 0);
break;
case 4:
Res::DrawIMG(CardX(k), CardY(i), "狼", 0);
break;
case 5:
Res::DrawIMG(CardX(k), CardY(i), "豹", 0);
break;
case 6:
Res::DrawIMG(CardX(k), CardY(i), "虎", 0);
break;
case 7:
Res::DrawIMG(CardX(k), CardY(i), "狮", 0);
break;
case 8:
Res::DrawIMG(CardX(k), CardY(i), "象", 0);
break;
case 9:
Res::DrawIMG(CardX(k), CardY(i), "鼠", 1);
break;
case 10:
Res::DrawIMG(CardX(k), CardY(i), "猫", 1);
break;
case 11:
Res::DrawIMG(CardX(k), CardY(i), "狗", 1);
break;
case 12:
Res::DrawIMG(CardX(k), CardY(i), "狼", 1);
break;
case 13:
Res::DrawIMG(CardX(k), CardY(i), "豹", 1);
break;
case 14:
Res::DrawIMG(CardX(k), CardY(i), "虎", 1);
break;
case 15:
Res::DrawIMG(CardX(k), CardY(i), "狮", 1);
break;
case 16:
Res::DrawIMG(CardX(k), CardY(i), "象", 1);
break;
}
}
else if (pData->getMap()[i][k] == 0)
{
Res::Draw_IMG(CardX(k), CardY(i), "路面");
}
}
}
}
button.h
#pragma once
#include "common.h"
#include"DrawImg.h"
#include"res.h"
#include "data.h"
#define CardW() 90 //图片宽
#define CardH() 108 //图片高
#define CardX(col) (28 + col * (CardW() + 42)) //28 左边的间隔 42 横向中间的间隔
#define CardY(row) (65 + row * (CardH() + 43)) //65 上边的间隔 43 横向中间的间隔
#define AT_Max 9
enum BothType
{
BT_Red,
BT_Blue
};
class Data;
/*———————————————————————————————————————————
鼠标按键控制:鼠标是地图变化的按键
————————————————————————————————————————————*/
class Button
{
public:
void ClickButton(ExMessage msg, Data* pData); /*鼠标操作的事件响应: 鼠标点击...*/
bool isIn(int x,int y,int left,int top,int w,int h);
//鼠标控制下棋
void luozi(Data* pData);
//消费者是否能吃食物
bool card_eat(Data* pData1, Data* pData2,int begRow, int begCol, int overRow, int overCol);
//获取
int card_type(Data* card,int i,int j)
{
if (card->getMap()[i][j] <= 8)
{
return BT_Blue;
}
else if (card->getMap()[i][j] && card->getMap()[i][j] < AT_Max * 2 - 1)
{
return BT_Red;
}
}
//两张牌类型是否相同
bool card_sameType(Data* pData1, Data* pData2, int begRow, int begCol,int overRow,int overCol)
{
return card_type(pData1, begRow,begCol) == card_type(pData2, overRow,overCol);
}
protected:
};
button.cpp
#include "button.h"
int curBothType = BT_Blue; //当前行棋方
enum State
{
Begin,
End
};
int press = Begin;//第一次点击还是第二次点击
struct Index
{
int row;
int col;
}beg = { -1,-1 }, over = { -1,-1 };
//判断某个坐标是否在矩形中
bool Button::isIn(int x, int y, int left, int top, int w, int h)
{
if (x > left && x < left + w && y > top && y < top + h)
{
return true;
}
return false;
}
void Button::ClickButton(ExMessage msg, Data* pData)
{
for (int i = 0; i < 4; i++)
{
for (int k = 0; k < 4; k++)
{
//判断是否点击当前下标的卡牌(i,k)
if (isIn(msg.x, msg.y, CardX(k), CardY(i), CardW(), CardH()))
{
//判断卡牌有没有被翻开,如果没有就翻开
if (pData->getMap()[i][k] > 20)
{
pData->changeValue(i, k, -20);
}
//如果翻开了判断能不能移动或者吃
else
{
//不管是移动还是吃,都需要记录前后两次的位置
//移动或者吃,需要知道两次点击的牌
if (press == Begin)
{
beg = { i,k };
press = End;
printf("begin(%d %d) %d\n", i, k, curBothType);
}
else if (press == End)
{
over = { i ,k };
press = Begin;
printf("end(%d %d) %d\n", i, k, curBothType);
}
}
}
}
}
}
void Button::luozi(Data* pData)
{
//beg end不为-1 并且不是同一个位置
if ((beg.row != -1 && over.row != -1) && !(beg.row == over.row && beg.col == over.col))
{
//在同一列或者同一行
if ((abs(beg.row - over.row) == 1 && beg.col == over.col) || (abs(beg.col - over.col) == 1 && beg.row == over.row))
{
//吃
bool ok = card_eat(pData,pData,over.row,over.col,beg.row, beg.col);
//移动
if (ok || pData->getMap()[over.row][over.col] == 0)
{
pData->getMap()[over.row][over.col] = pData->getMap()[beg.row][beg.col];
pData->getMap()[beg.row][beg.col] = 0;
beg = over = { -1,-1 };
//切换棋手
curBothType = (curBothType + 1) % 2;
}
}
}
}
bool Button::card_eat(Data* food, Data* consumer, int begRow, int begCol, int overRow, int overCol)
{//先把大于8的,也转成小于八的,方便比较
int ftype = food->getMap()[begRow][begCol];
int ctype = consumer->getMap()[overRow][overCol];
ftype = ftype > 8 ? food->getMap()[begRow][begCol] - 8 : ftype;
ctype = ctype > 8 ? consumer->getMap()[overRow][overCol] - 8 : ctype;
if (!card_sameType(food, consumer, begRow, begCol, overRow,overCol) && //不是同一方
ftype <= ctype || /*大吃小*/ (ftype == 8 && ctype == 1) //老鼠吃大象
)
{
return true;
}
return false;
}
c++斗兽棋.cpp
#include"DrawImg.h"
#include"data.h"
#include"button.h"
#include"res.h"
int main()
{
Draw draw;
Button* pp = new Button(); //按钮
ExMessage msg; //定义鼠标消息
while (true)
{
while (peekmessage(&msg, EM_MOUSE)) //获取鼠标消息
{
if (msg.message == WM_LBUTTONDOWN)
{
pp->ClickButton(msg, draw.getData());
}
}
draw.showData(); //显示数据
draw.Game_Draw(); //绘制
pp->luozi(draw.getData());
}
return 0;
}