一、说在前面
这是我第一个游戏,最近在学unity,也许这是我最后一个easyx游戏了。
二、代码
//common.h
#pragma once
#include<iostream>
#include<string>
#include<graphics.h>
#include<sstream>
#include<ctime>
#include<vector>
#include<mmsystem.h>
#include <fstream>
using namespace std;
#define WIDTH 60
#define HEIGHT 60
//main
#include"common.h"
#include"widget.h"
#include"button.h"
#include"timer.hpp"
#include"sudoku.h"
#pragma comment(lib,"winmm.lib")
int playtime, dif_i=0;
Sudoku sudoku;
ExMessage msg;
vector<string> dif = { "easy","medium","hard" };
Button restart(0, 10 * HEIGHT + 10, 3 * WIDTH, HEIGHT, RGB(230, 126, 34), LIGHTBLUE, RGB(230, 126, 34), "restart"),
submit(3 * WIDTH + 5, 10 * HEIGHT + 10, 3 * WIDTH, HEIGHT, RGB(230, 126, 34), LIGHTBLUE, RGB(230, 126, 34), "submit")
, Time(3 * WIDTH + 5, 0, 3 * WIDTH, HEIGHT, RGB(230, 126, 34), LIGHTBLUE, RGB(230, 126, 34), "00:00"),
Difficulty(6 * WIDTH + 10, 10 * HEIGHT + 10, 3 * WIDTH, HEIGHT, RGB(230, 126, 34), LIGHTBLUE, RGB(230, 126, 34), "easy"),
Over_submit(0, 0, 3 * WIDTH, HEIGHT, RGB(230, 126, 34), LIGHTBLUE, RGB(230, 126, 34), "00:00")
, nothing(6 * WIDTH + 10, 0, 3 * WIDTH, HEIGHT, RGB(230, 126, 34), LIGHTBLUE, RGB(230, 126, 34), "");
Widget w(9 * WIDTH + 10, 11 * HEIGHT + 10);
int DisplayResourceNAMessageBox()
{
int msgboxID = MessageBox(
NULL,
_T("恭喜!"),
_T("你赢了!是否重开?"),
MB_YESNO
);
switch (msgboxID) {
case IDYES:
sudoku.restartsudo();
playtime = clock();
break;
case IDNO:
w.~Widget();
break;
}
return msgboxID;
}
string putzero(string s) {
int all_length = 2;
string new_string = string(all_length - s.length(), '0')+s;
return new_string;
}
void SetTime() {
int now_play = clock()-playtime;
now_play /= 1000;
Time.Setword(putzero(to_string(now_play / 60)) + ":" + putzero(to_string(now_play % 60)));
}
int main() {
ifstream loadstream;
int over_submit = 0;
loadstream.open("save.txt");
loadstream >> over_submit;
Over_submit.Setword("all:" + to_string(over_submit));
loadstream.close();
w.Show();
BeginBatchDraw();
playtime = clock();
while (1) {
peekmessage(&msg, EM_MOUSE);
sudoku.DrawMap();
sudoku.MouseMessage(msg);
//其他按钮
restart.Show();
submit.Show();
Time.Show();
Difficulty.Show();
Over_submit.Show();
nothing.Show();
//按钮事件
SetTime();
//重开
if (restart.ClickButton(msg) == true) {
sudoku.restartsudo();
Sleep(200);
playtime = clock();
}
//提交
if (submit.ClickButton(msg) == true&&sudoku.gameover()==true) {
DisplayResourceNAMessageBox();
ofstream savestream;
over_submit++;
savestream.open("save.txt");
savestream << over_submit;
Over_submit.Setword("all:"+to_string(over_submit));
}
//难易度
if (Difficulty.ClickButton(msg) == true&& Timer::sTimer(200, 1)) {
dif_i = (dif_i + 1) % 3;
Difficulty.Setword(dif[dif_i]);
sudoku.sethole();
sudoku.restartsudo();
}
FlushBatchDraw();
}
EndBatchDraw();
return 0;
}
//botton.h
#pragma once
#include"common.h"
class Button {
public:
Button(int x, int y, int w, int h, COLORREF curColor, COLORREF inColor, COLORREF outColor, string text);
void Show();
bool MouseInButton(ExMessage& msg);
bool ClickButton(ExMessage& msg);
void SetText();
void Setword(string word);
void playsong();
protected:
int x;
int y;
int w;
int h;
COLORREF curColor;
COLORREF inColor;
COLORREF outColor;
string text;
};
//botton.cpp
#include "button.h"
#include "timer.hpp"
#include "sudoku.h"
#include "common.h"
#pragma comment(lib,"winmm.lib")
Button::Button(int x, int y, int w, int h, COLORREF curColor, COLORREF inColor, COLORREF outColor, string text)
{
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->curColor = curColor;
this->outColor = outColor;
this->inColor = inColor;
this->text = text;
}
void Button::Show()
{
setfillcolor(this->curColor);
setlinecolor(BLACK);
settextcolor(BLACK);
fillrectangle(x, y, x + w, y + h);
settextstyle(h * 2 / 3, 0, "黑体");
setbkmode(TRANSPARENT);
int xx = x + (w - textwidth(text.c_str())) / 2;
int yy = y + (h - textheight(text.c_str())) / 2;
outtextxy(xx, yy, text.c_str());
}
bool Button::MouseInButton(ExMessage& msg)
{
if (msg.x > x && msg.x<x + w && msg.y>y && msg.y < y + h) {
this->curColor = this->inColor;
return true;
}
this->curColor = this->outColor;
return false;
}
bool Button::ClickButton(ExMessage& msg)
{
if (MouseInButton(msg)&&msg.message== WM_LBUTTONDOWN)
{
playsong();
return true;
}
return false;
}
void Button::SetText()
{
stringstream stream(text);
int num = 0;
stream >> num;
num++;
num = num % 10;
this->text = to_string(num);
}
void Button::Setword(string word)
{
this->text = word;
}
void Button::playsong()
{
PlaySound(_T("res\\click2.wav"), NULL, SND_FILENAME | SND_ASYNC);
Sleep(200);
}
//widget.h
#pragma once
//窗口类
class Widget
{
public:
Widget(int width, int height);
void Show();
~Widget();
protected:
int width;
int height;
};
//sudoku.h
#pragma once
#include"common.h"
#include"button.h"
class Sudoku {
public:
Sudoku();
void DrawMap();
int ClickButton(ExMessage& msg);
bool gameover();
void MouseMessage(ExMessage& msg);
void restartsudo();
void sethole();
int n[3] = { 4,6,9 }, gy[3] = { 2,2,3 }, gx[3] = { 2,3,3 }, bc = 1;
int l = 2;
bool set(int x, int y, int val) {
if (sudo[y][x] != 0)
return false;
for (int x0 = 0; x0 < n[l]; x0++) {
if (sudo[y][x0] == val)
return false;
}
for (int y0 = 0; y0 < n[l]; y0++) {
if (sudo[y0][x] == val)
return false;
}
for (int y0 = y / gy[l] * gy[l]; y0 < y / gy[l] * gy[l] + gy[l]; y0++) {
for (int x0 = x / gx[l] * gx[l]; x0 < x / gx[l] * gx[l] + gx[l]; x0++) {
if (sudo[y0][x0] == val)
return false;
}
}
sudo[y][x] = val;
return true;
}
void randinit(int* ox) {
srand(clock());
int k, tmp;
for (int i = 0; i < n[l]; i++) {
ox[i] = i;
}
for (int i = 0; i < n[l]; i++) {
k = rand() % n[l];
tmp = ox[k];
ox[k] = ox[i];
ox[i] = tmp;
}
}
void reset(int x, int y) { sudo[y][x] = 0; }
int fillsudo(int y, int val) {
int ox[9];
randinit(ox);
for (int i = 0; i < n[l]; i++) {
int x = ox[i];
if (set(x, y, val)) {
if (y == n[l] - 1) {
if (val == n[l] || fillsudo(0, val + 1))
return true;
}
else {
if (fillsudo(y + 1, val))
return true;
}
reset(x, y);
}
}
return false;
}
void dighole(int con) {
srand(clock());
int k = 0;
for (int i = 0; i < n[l]; i++) {
for (int j = 0; j < n[l]; j++) {
if (k<con&&rand()%9<con/9) {
sudo[i][j] = 0;
k++;
}
}
}
}
protected:
vector<pair<bool, Button*>> rect;
int sudo[9][9], map[9][9];
};
//sudoku.cpp
#include "sudoku.h"
#include "common.h"
#include "timer.hpp"
int hole=27;
Sudoku::Sudoku()
{
rect.clear();
while (fillsudo(1, 1)) {};
for (int i = 0; i < 9; i++) {
if (sudo[0][i] == 0)sudo[0][i] = 1;
}
//dighole(hole);
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
int x = WIDTH * j + j / 3 * 5;
int y = HEIGHT * i + i / 3 * 5+60;
if (sudo[i][j] != 0) {
//不可修改绿色
rect.push_back(make_pair<bool, Button*>
(false, new Button(x,y,WIDTH, HEIGHT, LIGHTGRAY, LIGHTBLUE, LIGHTGRAY, to_string(sudo[i][j]))));
}
else {
//红色作答区
rect.push_back(make_pair<bool, Button*>
(true, new Button(x, y, WIDTH, HEIGHT, WHITE, LIGHTBLUE, WHITE, to_string(sudo[i][j]))));
}
map[i][j] = sudo[i][j];
}
}
}
void Sudoku::DrawMap()
{
for (auto v : rect) {
v.second->Show();
}
}
int Sudoku::ClickButton(ExMessage& msg)
{
for (int i = 0; i < rect.size(); i++) {
if (rect[i].second->ClickButton(msg) == true) {
map[int(i / 9)][int(i % 9)] = (map[int(i / 9)][int(i % 9)]+1)%10;
return i;
}
}
return -1;
}
bool Sudoku::gameover()
{
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (map[i][j] == 0)return false;
for (int k = 0; k < 9; k++) {
if (k != i && map[i][j] == map[k][j])return false;
if (k != j && map[i][j] == map[i][k])return false;
}
int gi = i / 3 * 3, gj = j / 3 * 3;
for (int k = gi; k < gi + 3; k++) {
for (int g = gj; g < gj + 3; g++) {
if (k != i && j != g && map[i][j] == map[k][g])return false;
}
}
}
}
return true;
}
void Sudoku::MouseMessage(ExMessage& msg)
{
int pos = ClickButton(msg);
if (pos != -1 && rect[pos].first == true) {
rect[pos].second->SetText();
}
}
void Sudoku::restartsudo()
{
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
sudo[i][j] = 0;
}
}
while (fillsudo(1, 1)) {};
for (int i = 0; i < 9; i++) {
if (sudo[0][i] == 0)sudo[0][i] = 1;
}
dighole(hole);
while (rect.empty() == false) {
rect.pop_back();
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
int x = WIDTH * j + j / 3 * 5;
int y = HEIGHT * i + i / 3 * 5+60;
if (sudo[i][j] != 0) {
//不可修改绿色
rect.push_back(make_pair<bool, Button*>
(false, new Button(x, y, WIDTH, HEIGHT, LIGHTGRAY, LIGHTBLUE, LIGHTGRAY, to_string(sudo[i][j]))));
}
else {
//红色作答区
rect.push_back(make_pair<bool, Button*>
(true, new Button(x, y, WIDTH, HEIGHT, WHITE, LIGHTBLUE, WHITE, to_string(sudo[i][j]))));
}
map[i][j] = sudo[i][j];
}
}
}
//3 5 6
void Sudoku::sethole()
{
switch (hole) {
case 27:hole = 45; break;
case 45:hole = 54; break;
case 54:hole = 27; break;
}
}
//timer.cpp
#pragma once
#include"common.h"
static int starttime[10];
class Timer {
public:
static bool sTimer(int duration, int id) {
int endtime = clock();
if (endtime - starttime[id] > duration) {
starttime[id] = endtime;
return true;
}
return false;
}
};
一定一定一定要装easyx库
文件资源我放在资源里了