VS2022制作的数独游戏

一、说在前面

这是我第一个游戏,最近在学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库

文件资源我放在资源里了

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 Python 制作数独游戏的源代码,使用 Pygame 库实现游戏界面: ``` import pygame import numpy as np import time pygame.init() # 游戏窗口尺寸 WINDOW_SIZE = (540, 600) # 游戏窗口标题 pygame.display.set_caption("数独游戏") # 游戏窗口 screen = pygame.display.set_mode(WINDOW_SIZE) # 数独棋盘 board = np.array([[7, 8, 0, 4, 0, 0, 1, 2, 0], [6, 0, 0, 0, 7, 5, 0, 0, 9], [0, 0, 0, 6, 0, 1, 0, 7, 8], [0, 0, 7, 0, 4, 0, 2, 6, 0], [0, 0, 1, 0, 5, 0, 9, 3, 0], [9, 0, 4, 0, 6, 0, 0, 0, 5], [0, 7, 0, 3, 0, 0, 0, 1, 2], [1, 2, 0, 0, 0, 7, 4, 0, 0], [0, 4, 9, 2, 0, 6, 0, 0, 7]]) # 数独棋盘位置 BOARD_POS = (20, 80) # 数字方格尺寸 CELL_SIZE = 50 # 数字方格颜色 CELL_COLOR = (255, 255, 255) # 数字方格线宽 CELL_LINE_WIDTH = 1 # 数字字体 FONT = pygame.font.SysFont('Arial', 36) # 游戏是否结束 game_over = False # 绘制数独棋盘 def draw_board(): for i in range(9): for j in range(9): pygame.draw.rect(screen, CELL_COLOR, (BOARD_POS[0] + j*CELL_SIZE, BOARD_POS[1] + i*CELL_SIZE, CELL_SIZE, CELL_SIZE), 0) pygame.draw.rect(screen, (0, 0, 0), (BOARD_POS[0] + j*CELL_SIZE, BOARD_POS[1] + i*CELL_SIZE, CELL_SIZE, CELL_SIZE), CELL_LINE_WIDTH) if board[i][j] != 0: text = FONT.render(str(board[i][j]), True, (0, 0, 0)) text_rect = text.get_rect() text_rect.center = (BOARD_POS[0] + (j+0.5)*CELL_SIZE, BOARD_POS[1] + (i+0.5)*CELL_SIZE) screen.blit(text, text_rect) # 检查数独是否解决 def check_win(): for i in range(9): for j in range(9): if board[i][j] == 0: return False return True # 显示游戏结束画面 def show_game_over(): text = FONT.render("游戏结束", True, (0, 0, 0)) text_rect = text.get_rect() text_rect.center = (WINDOW_SIZE[0] / 2, WINDOW_SIZE[1] / 2 - 50) screen.blit(text, text_rect) text2 = FONT.render("按 R 重新开始", True, (0, 0, 0)) text2_rect = text2.get_rect() text2_rect.center = (WINDOW_SIZE[0] / 2, WINDOW_SIZE[1] / 2 + 50) screen.blit(text2, text2_rect) # 重置游戏 def reset_game(): global board, game_over board = np.array([[7, 8, 0, 4, 0, 0, 1, 2, 0], [6, 0, 0, 0, 7, 5, 0, 0, 9], [0, 0, 0, 6, 0, 1, 0, 7, 8], [0, 0, 7, 0, 4, 0, 2, 6, 0], [0, 0, 1, 0, 5, 0, 9, 3, 0], [9, 0, 4, 0, 6, 0, 0, 0, 5], [0, 7, 0, 3, 0, 0, 0, 1, 2], [1, 2, 0, 0, 0, 7, 4, 0, 0], [0, 4, 9, 2, 0, 6, 0, 0, 7]]) game_over = False # 游戏循环 while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_r and game_over: reset_game() if event.type == pygame.MOUSEBUTTONDOWN and not game_over: pos = pygame.mouse.get_pos() if pos[0] >= BOARD_POS[0] and pos[1] >= BOARD_POS[1] and pos[0] < BOARD_POS[0] + 9*CELL_SIZE and pos[1] < BOARD_POS[1] + 9*CELL_SIZE: row = (pos[1] - BOARD_POS[1]) // CELL_SIZE col = (pos[0] - BOARD_POS[0]) // CELL_SIZE if board[row][col] == 0: for i in range(1, 10): if np.count_nonzero(board[row] == i) == 0 and np.count_nonzero(board[:, col] == i) == 0: box_x = col // 3 box_y = row // 3 if np.count_nonzero(board[box_y*3:box_y*3+3, box_x*3:box_x*3+3] == i) == 0: board[row][col] = i if check_win(): game_over = True screen.fill((255, 255, 255)) draw_board() if game_over: show_game_over() pygame.display.update() ``` 运行结果: ![数独游戏界面](https://i.imgur.com/n9NfLQ5.png)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值