设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2319|回复: 5
打印 上一主题 下一主题

[原创发布] 如何使用C++制作数独小游戏(大雾)

[复制链接]

Lv3.寻梦者

梦石
0
星屑
1803
在线时间
133 小时
注册时间
2013-10-6
帖子
193
跳转到指定楼层
1
发表于 2018-1-25 02:07:58 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
刚才看到了这个如何使用RPGMaker制作数独小游戏
然后闲得蛋疼花了一小时用C++写了个控制台版本的】明早还赶飞机呀 赶紧先滚床了
支持鼠标键盘操作,输入数字填入,Backspace删除




逻辑封装在Sudoku class里了 应该很好写成JS/Ruby吧 来试试?】@无终
随机生成的话rand一下就可以了】class里有判别准则

CPP 代码复制
  1. #include <iostream>
  2. #include <sstream>
  3. #include <Windows.h>
  4. #include <fstream>
  5. #include <string>
  6. using namespace std;
  7.  
  8. struct Grid {
  9.         int number = 0;
  10.         bool is_fixed = false;
  11. };
  12.  
  13. class Sudoku {
  14. public:
  15.         Sudoku() {
  16.                 init();
  17.         }
  18.         void init() {
  19.                 for (int row = 0; row < 9; ++row) {
  20.                         for (int col = 0; col < 9; ++col) {
  21.                                 data[row][col] = Grid();
  22.                         }
  23.                 }
  24.         }
  25.         void set_fixed(int r, int c, int n) {
  26.                 Grid& g = data[r][c];
  27.                 g.number = n;
  28.                 g.is_fixed = true;
  29.         }
  30.         bool set(int r, int c, int n) {
  31.                 if (data[r][c].is_fixed) {
  32.                         return false;
  33.                 }
  34.                 bool valid = true;
  35.                 auto validator = [&](Grid g) {
  36.                         if (g.number == n) {
  37.                                 valid = false;
  38.                         }
  39.                 };
  40.                 if (n != 0) {
  41.                         get_each_in_row(r, c, validator);
  42.                         get_each_in_col(r, c, validator);
  43.                         get_each_in_block(r, c, validator);
  44.                 }
  45.                 if (valid) {
  46.                         data[r][c].number = n;
  47.                 }
  48.                 return valid;
  49.         }
  50.         bool finished() {
  51.                 for (int r = 0; r < 9; ++r) {
  52.                         for (int c = 0; c < 9; ++c) {
  53.                                 if (data[r][c].number == 0) {
  54.                                         return false;
  55.                                 }
  56.                         }
  57.                 }
  58.                 return true;
  59.         }
  60.         Grid get(int r, int c) {
  61.                 return data[r][c];
  62.         }
  63. private:
  64.         Grid data[9][9];
  65.         template<typename Fn>
  66.         void get_each_in_row(int r, int c, Fn f) {
  67.                 for (int i = 0; i < 9; ++i) {
  68.                         if (i != c) {
  69.                                 f(data[r][i]);
  70.                         }
  71.                 }
  72.         }
  73.         template<typename Fn>
  74.         void get_each_in_col(int r, int c, Fn f) {
  75.                 for (int i = 0; i < 9; ++i) {
  76.                         if (i != r) {
  77.                                 f(data[i][c]);
  78.                         }
  79.                 }
  80.         }
  81.         template<typename Fn>
  82.         void get_each_in_block(int r, int c, Fn f) {
  83.                 int block_rn = r / 3;
  84.                 int block_cn = c / 3;
  85.                 for (int br = 0; br < 3; ++br) {
  86.                         for (int bc = 0; bc < 3; ++bc) {
  87.                                 int data_r = block_rn * 3 + br;
  88.                                 int data_c = block_cn * 3 + bc;
  89.                                 if (data_r != r && data_c != c) {
  90.                                         f(data[data_r][data_c]);
  91.                                 }
  92.                         }
  93.                 }
  94.         }
  95. };
  96.  
  97. void move_to(int x, int y) {
  98.         HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
  99.         COORD coord;
  100.         coord.X = x;
  101.         coord.Y = y;
  102.         SetConsoleCursorPosition(hStdOut, coord);
  103. }
  104.  
  105. template<typename T>
  106. void print(const T& arg) {
  107.         wstringstream ss;
  108.         ss << arg;
  109.         HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
  110.         DWORD charsWritten;
  111.         wstring str = ss.str();
  112.         WriteConsoleW(hStdOut, str.c_str(), str.size(), &charsWritten, NULL);
  113. }
  114.  
  115. template<typename T1, typename T2, typename... Ts>
  116. void print(const T1& arg1, const T2& arg2, Ts... rest) {
  117.         wstringstream ss;
  118.         ss << arg1 << arg2;
  119.         print(ss.str(), rest...);
  120. }
  121.  
  122. void set_color(WORD color) {
  123.         HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
  124.         SetConsoleTextAttribute(hStdOut, color);
  125. }
  126.  
  127. void set_color() {
  128.         set_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
  129. }
  130.  
  131. int main(int argc, char* argv[]) {
  132.         Sudoku game;
  133.         ifstream in("data.txt", ios::in);
  134.         if (in) {
  135.                 int row = 0;
  136.                 string line;
  137.                 while (getline(in, line)) {
  138.                         int col = 0;
  139.                         for (char ch : line) {
  140.                                 if (ch >= '1'&&ch <= '9') {
  141.                                         game.set_fixed(row, col, ch - '0');
  142.                                 }
  143.                                 ++col;
  144.                                 if (col >= 9) {
  145.                                         break;
  146.                                 }
  147.                         }
  148.                         ++row;
  149.                         if (row >= 9) {
  150.                                 break;
  151.                         }
  152.                 }
  153.                 in.close();
  154.         }
  155.         HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
  156.         DWORD mode;
  157.         GetConsoleMode(hStdIn, &mode);
  158.         mode &= ~ENABLE_QUICK_EDIT_MODE;
  159.         SetConsoleMode(hStdIn, mode);
  160.         DWORD recordsRead;
  161.         INPUT_RECORD record;
  162.         int sel_x = 0, sel_y = 0;
  163.         bool invalidated = true;
  164.         while (true) {
  165.                 if (invalidated) {
  166.                         for (int r = 0; r < 9; ++r) {
  167.                                 for (int c = 0; c < 9; ++c) {
  168.                                         move_to(c, r);
  169.                                         Grid g = game.get(r, c);
  170.                                         if (r == sel_y && c == sel_x) {
  171.                                                 set_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
  172.                                         }
  173.                                         else {
  174.                                                 if (g.is_fixed) {
  175.                                                         set_color(FOREGROUND_GREEN | FOREGROUND_INTENSITY);
  176.                                                 }
  177.                                                 else {
  178.                                                         set_color();
  179.                                                 }
  180.                                         }
  181.                                         if (g.number == 0) {
  182.                                                 print('.');
  183.                                         }
  184.                                         else {
  185.                                                 print(g.number);
  186.                                         }
  187.                                 }
  188.                         }
  189.                         if (game.finished()) {
  190.                                 break;
  191.                         }
  192.                         invalidated = false;
  193.                 }
  194.                 ReadConsoleInputW(hStdIn, &record, 1, &recordsRead);
  195.                 if (record.EventType == MOUSE_EVENT) {
  196.                         auto evt = record.Event.MouseEvent;
  197.                         if (evt.dwEventFlags == 0) {
  198.                                 auto pos = evt.dwMousePosition;
  199.                                 if (evt.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) {
  200.                                         if (pos.X >= 0 && pos.X < 9 && pos.Y >= 0 && pos.Y < 9) {
  201.                                                 sel_x = pos.X;
  202.                                                 sel_y = pos.Y;
  203.                                                 invalidated = true;
  204.                                         }
  205.                                 }
  206.                         }
  207.                 }
  208.                 else if (record.EventType == KEY_EVENT) {
  209.                         auto evt = record.Event.KeyEvent;
  210.                         if (evt.bKeyDown) {
  211.                                 if (evt.wVirtualKeyCode >= '1'&&evt.wVirtualKeyCode <= '9') {
  212.                                         int num = evt.wVirtualKeyCode - '0';
  213.                                         if (game.set(sel_y, sel_x, num)) {
  214.                                                 invalidated = true;
  215.                                         }
  216.                                 }
  217.                                 else if (evt.wVirtualKeyCode == VK_BACK) {
  218.                                         if (game.set(sel_y, sel_x, 0)) {
  219.                                                 invalidated = true;
  220.                                         }
  221.                                 }
  222.                                 else {
  223.                                         switch (evt.wVirtualKeyCode) {
  224.                                         case VK_UP:
  225.                                                 if (sel_y > 0) {
  226.                                                         --sel_y;
  227.                                                         invalidated = true;
  228.                                                 }
  229.                                                 break;
  230.                                         case VK_DOWN:
  231.                                                 if (sel_y < 8) {
  232.                                                         ++sel_y;
  233.                                                         invalidated = true;
  234.                                                 }
  235.                                                 break;
  236.                                         case VK_LEFT:
  237.                                                 if (sel_x > 0) {
  238.                                                         --sel_x;
  239.                                                         invalidated = true;
  240.                                                 }
  241.                                                 break;
  242.                                         case VK_RIGHT:
  243.                                                 if (sel_x < 8) {
  244.                                                         ++sel_x;
  245.                                                         invalidated = true;
  246.                                                 }
  247.                                                 break;
  248.                                         }
  249.                                 }
  250.                         }
  251.                 }
  252.         }
  253.         move_to(0, 9);
  254.         set_color();
  255.         print("Congratulations!\n");
  256.         system("pause");
  257. }

Sudoku.zip

130.78 KB, 下载次数: 99

←你看到一只经常潜水的萌新。

Lv2.观梦者

梦石
0
星屑
548
在线时间
73 小时
注册时间
2017-12-22
帖子
42
2
发表于 2018-1-25 10:31:59 | 只看该作者
大神
我并不会Ruby或者JS的呀...
游戏爱好者
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
0
星屑
31908
在线时间
5080 小时
注册时间
2012-11-19
帖子
4877

开拓者

3
发表于 2018-1-25 11:29:21 | 只看该作者
然而我连数独怎么玩都不知道。
xp vx va mv  va mz 各类型脚本/插件定制
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1239
在线时间
668 小时
注册时间
2009-11-11
帖子
2787
4
发表于 2018-1-25 12:41:50 | 只看该作者
我猜LZ母语是C++

点评

在脑子极度不清醒的情况下我只剩下会C/C++了  发表于 2018-1-25 22:24
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9275
在线时间
2504 小时
注册时间
2011-5-20
帖子
15389

开拓者

5
发表于 2018-1-25 13:09:49 | 只看该作者
芯☆淡茹水 发表于 2018-1-25 11:29
然而我连数独怎么玩都不知道。

一般数独是填在一个矩形范围,横竖的一行(奇数x奇数范围的情况会计算斜着的一行),以及小区域内的数字不能出现重复
看到楼主给的链接里面是事件
rm做的话···你如果想用脚本做,首先要设定一下题目给出的格子(数独不一定是标准图形)、一些小范围里的格子

需要预设定数字的初始值给负数,需要自己输入的就给0,显示出来的时候用绝对值,值小于0的格子不能修改

在提交完成的数独时做判定是否满足(通过)

大概是:先把每横排的数值的绝对值扔进一个数组,然后判断去掉重复值后的元素数量是否和不去掉重复值的元素数量相等

竖排同理

最后判定小区域内的是否满足不重复数字的情况
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-24 00:46

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表