基于C語言自制華容道游戲的示例代碼
程序簡介
華容道,畫風(fēng)參考的是手機程序:超級華容道。玩法是將大塊移動至下層的中間。隨機盤面,難度適中,自動解題。
程序隨機了橫塊縱塊數(shù)量,所以會有無解或難解,生成函數(shù)保證了加載出來的盤面是可玩的,但不保證每次生成的都可玩,所以需要有個等待過程。編碼函數(shù)和解碼函數(shù)是輔助解題的,解題思路是移動僅有的兩個空格,包括兩個空格移動,和一個空格移動。游戲下方從左往右是播放,重置,刷新按鈕。點擊播放開始輸出解題過程;點擊重置返回盤面初始狀態(tài),在游戲過程和播放完畢后使用;刷新即重新生成盤面。沒有剪枝,面對類似橫刀立馬這類難解,只能分段求解才可以。這個程序直接舍棄這種題目了。
更新過加入了站內(nèi)同學(xué)給出的十二張標(biāo)準(zhǔn)譜面,將求解作為按鈕單獨隔開,這十二關(guān)都可以解出來;因此隨機生成譜面會有無解的可能,按求解會判斷出來。明確了玩法,將出口標(biāo)記了出來;點擊棋子選中,點擊相鄰空格移動。
程序執(zhí)行效果

完整源代碼
// 程序:華容道
// 編譯環(huán)境:Visual C++ 2010,EasyX_20211109
// 編寫日期:2023.2.18
# include <math.h>
# include <graphics.h>
# include <time.h>
# include <string>
static HWND hOut; // 畫布
// 定義一個結(jié)構(gòu)體,樹
struct Node1
{
int num; // 編號
int num_transverse; // 橫向特征值
int num_portrait; // 縱向特征值
int num_other; // 其他特征值
int num_father; // 父結(jié)點
};
Node1 box[200001]; // 預(yù)制結(jié)點
// 定義一個結(jié)構(gòu)體,臨時存放
struct Node2
{
int num_transverse; // 橫向特征值
int num_portrait; // 縱向特征值
int num_other; // 其他特征值
};
// 定義一個結(jié)構(gòu)體,按鈕
struct Node3
{
int posx1, posy1, posx2, posy2; // 坐標(biāo)
};
// 定義一個類
class Gary
{
public:
void carry(); // 主進程
void initialization(); // 初始化
void move(); // 窗口主視角函數(shù)
void draw_scene(int num_box); // 繪制界面函數(shù)
void create(); // 生成函數(shù)
void decode(); // 解碼函數(shù)
void code(); // 編碼函數(shù)
void check(int a, int b, int c); // 檢測重復(fù)函數(shù)
void single_space(int mode); // 單格移動函數(shù)
void double_space(); // 雙哥移動函數(shù)
void over(); // 結(jié)束判斷函數(shù)
void game(); // 游戲函數(shù)
void solve(); // 求解函數(shù)
int exit_carry; // 主循函數(shù)控制參數(shù)
int exit_move; // 開始界面控制參數(shù)
int num_double[31]; // 輔助數(shù)據(jù)存入
int num_step; // 樹層數(shù)
int num_eat; // 求解鏈長度參數(shù)
int num_start; // 求解起點參數(shù)
int num_over; // 求解終點參數(shù)
int num_mod; // 游戲模式
int box_transverse[6]; // 橫向
int box_portrait[6]; // 縱向
int box_big; // 大格
int box_space[2]; // 空格
int num_transverse; // 橫向數(shù)量
int num_portrait; // 縱向數(shù)量
int pan[30]; // 棋盤信息
double num_flag; // 樹結(jié)點標(biāo)記系數(shù)
double num_flag1; // 樹結(jié)點標(biāo)記系數(shù)
IMAGE* img_transverse; // 橫塊圖片
IMAGE* img_portrait; // 縱塊圖片
IMAGE* img_small; // 小塊圖片
IMAGE* img_big; // 大塊圖片
IMAGE* img_space; // 空格圖片
ExMessage m; // 鼠標(biāo)定義
Node2 eat[200]; // 臨時存放結(jié)點
Node3 box_button[20]; // 按鈕,預(yù)制
};
// 場景繪制函數(shù)
void Gary::draw_scene(int num_box)
{
int i, j;
// 橫向
for(i = 0; i < num_transverse; i++)
{
box_transverse[i] = ( eat[num_box].num_transverse & ( num_double[i * 5 + 5] - num_double[i * 5] ) ) / num_double[i * 5];
}
// 縱向
for(i = 0; i < num_portrait; i++)
{
box_portrait[i] = ( eat[num_box].num_portrait & ( num_double[i * 5 + 5] - num_double[i * 5] ) ) / num_double[i * 5];
}
// 大格
box_big = ( eat[num_box].num_other & ( num_double[21] - num_double[16] ) ) / num_double[16];
// 空格
box_space[0] = ( eat[num_box].num_other & ( num_double[13] - num_double[8] ) ) / num_double[8];
box_space[1] = ( eat[num_box].num_other & ( num_double[5] - num_double[0] ) );
// 初始化
for(i = 0; i < 20; i++)
{
pan[i] = -1;
}
// 橫向
for(i = 0; i < num_transverse; i++)
{
pan[box_transverse[i]] = 2;
pan[box_transverse[i] + 1] = 5;
}
// 縱向
for(i = 0; i < num_portrait; i++)
{
pan[box_portrait[i]] = 3;
pan[box_portrait[i] + 4] = 5;
}
// 大格
pan[box_big] = 1;
pan[box_big + 1] = 5;
pan[box_big + 4] = 5;
pan[box_big + 5] = 5;
// 空格
pan[box_space[0]] = 0;
pan[box_space[1]] = 0;
// 小塊
for(j = 0; j < 20; j++)
{
if(pan[j] == -1)
{
pan[j] = 4;
}
}
// 背景繪制
setbkcolor(RGB(136, 192, 160));
cleardevice();
// 棋盤繪制
setlinestyle(PS_SOLID, 3);
setfillcolor(RGB(73, 130, 120));
setlinecolor(RGB(168, 226, 195));
fillroundrect(20, 15, 25 + 102 * 4, 30 + 102 * 5, 30, 30);
for(i = 0; i < 20; i++)
{
// 根據(jù)格子類型繪制
switch(pan[i])
{
case 0:putimage(25 + i % 4 * 102, 25 + i / 4 * 102, img_space); break;
case 1:putimage(25 + i % 4 * 102, 25 + i / 4 * 102, img_big); break;
case 2:putimage(25 + i % 4 * 102, 25 + i / 4 * 102, img_transverse); break;
case 3:putimage(25 + i % 4 * 102, 25 + i / 4 * 102, img_portrait); break;
case 4:putimage(25 + i % 4 * 102, 25 + i / 4 * 102, img_small); break;
default:break;
}
// 出口繪制
if(pan[i] == 0 && ( i == 13 || i == 14 || i == 17 || i == 18 ))
{
setlinecolor(RGB(230, 230, 230));
setlinestyle(PS_SOLID, 10);
setfillcolor(RGB(112, 180, 167));
fillcircle(25 + 51 + i % 4 * 102, 25 + 51 + i / 4 * 102, 20);
setlinecolor(RGB(168, 226, 195));
setfillcolor(RGB(73, 130, 120));
setlinestyle(PS_SOLID, 3);
}
}
// 按鈕繪制
TCHAR s[25];
setlinecolor(RGB(155, 195, 230));
setfillcolor(RGB(80, 189, 222));
settextcolor(RGB(230, 230, 230));
settextstyle(30, 20, _T("Times New Roman"));
setbkcolor(RGB(80, 189, 222));
// 標(biāo)準(zhǔn)棋盤按鈕
for(i = 0; i < 12; i++)
{
fillroundrect(box_button[i].posx1, box_button[i].posy1, box_button[i].posx2, box_button[i].posy2, 20, 20);
_stprintf_s(s, _T("%d"), i);
outtextxy(box_button[i].posx1 + 13 - 11 * ( i / 10 ), box_button[i].posy1 + 10, s);
}
// 其他按鈕
settextstyle(100, 100, _T("Webdings"));
settextcolor(RGB(73, 130, 120));
setbkmode(TRANSPARENT);
// 播放,求解
outtextxy(102 - 50, 580 - 30, 0x34);
// 重置,恢復(fù)初始盤面
outtextxy(214 - 50, 580 - 30, 0x33);
// 刷新,隨機盤面按鈕
outtextxy(326 - 50, 580 - 30, 0x71);
// 恢復(fù)填充
setbkmode(OPAQUE);
settextcolor(RGB(230, 230, 230));
settextstyle(30, 20, _T("宋體"));
setbkcolor(RGB(136, 192, 160));
outtextxy(102 - 50, 655, _T("求解"));
outtextxy(214 - 50, 655, _T("恢復(fù)"));
outtextxy(326 - 50, 655, _T("刷新"));
FlushBatchDraw();
}
// 解碼
void Gary::decode()
{
int i;
// 根據(jù)特征值畫棋面
// 橫向
for(i = 0; i < num_transverse; i++)
{
box_transverse[i] = ( box[int(num_flag)].num_transverse & ( num_double[i * 5 + 5] - num_double[i * 5] ) ) / num_double[i * 5];
}
// 縱向
for(i = 0; i < num_portrait; i++)
{
box_portrait[i] = ( box[int(num_flag)].num_portrait & ( num_double[i * 5 + 5] - num_double[i * 5] ) ) / num_double[i * 5];
}
// 大格
box_big = ( box[int(num_flag)].num_other & ( num_double[21] - num_double[16] ) ) / num_double[16];
// 空格
box_space[0] = ( box[int(num_flag)].num_other & ( num_double[13] - num_double[8] ) ) / num_double[8];
box_space[1] = ( box[int(num_flag)].num_other & ( num_double[5] - num_double[0] ) );
}
// 檢查重復(fù)函數(shù)
void Gary::check(int a, int b, int c)
{
int k, t;
// 全局檢測
k = 0;
for(t = int(num_flag1 - 1); t >= 0; t--)
{
if(box[t].num_transverse == a && box[t].num_portrait == b && box[t].num_other == c) { k = 1; break; }
}
// 不重復(fù)則生成子結(jié)點
if(k == 0)
{
// 特征值錄入,父結(jié)點錄入
box[int(num_flag1)].num_transverse = a;
box[int(num_flag1)].num_portrait = b;
box[int(num_flag1)].num_other = c;
box[int(num_flag1)].num_father = int(num_flag);
// 編號
box[int(num_flag1)].num = box[box[int(num_flag1)].num_father].num + 1;
// 層數(shù)
if(box[int(num_flag1)].num > num_step)
{
// 加層
num_step = box[int(num_flag1)].num;
// 進度條繪制
setlinecolor(RGB(155, 195, 230));
setfillcolor(RGB(155, 195, 230));
fillroundrect(50, 640, int(70.0 + 330.0 * double(num_eat + num_step) / 120.0), 650, 20, 20);
FlushBatchDraw();
}
// 標(biāo)記加一
num_flag1++;
}
}
// 單空格移動函數(shù)
void Gary::single_space(int mode)
{
int i, j, k;
int a, b, c;
int t;
// 空格讀取
i = box_big;
j = ( mode == 0 ? box_space[0] : box_space[1] );
k = ( mode == 0 ? box_space[1] : box_space[0] );
// 空格
// 上(不是大塊,不是另一個空格,不在最上測,不是橫塊)
if(j - 4 != i + 4 && j - 4 != i + 5 && j - 4 != k && j > 3)
{
for(t = 0; t < num_transverse; t++)
{
if(j - 4 == box_transverse[t] || j - 4 == box_transverse[t] + 1)break;
}
// 不是橫塊
if(t == num_transverse)
{
for(t = 0; t < num_portrait; t++)
{
if(j - 4 == box_portrait[t] + 4)break;
}
a = box[int(num_flag)].num_transverse;
// 不是縱塊
if(t == num_portrait)
{
b = box[int(num_flag)].num_portrait;
c = ( mode == 0 ? ( i * num_double[16] + ( j - 4 ) * num_double[8] + k * num_double[0] ) : ( i * num_double[16] + k * num_double[8] + ( j - 4 ) * num_double[0] ) );
}
// 是
else
{
b = box[int(num_flag)].num_portrait + 4 * num_double[t * 5];
c = ( mode == 0 ? ( i * num_double[16] + ( j - 8 ) * num_double[8] + k * num_double[0] ) : ( i * num_double[16] + k * num_double[8] + ( j - 8 ) * num_double[0] ) );
}
check(a, b, c);
}
}
// 下(不是大塊,不是另一個空格,不在最下測,不是橫塊)
if(j + 4 != i && j + 4 != i + 1 && j + 4 != k && j < 16)
{
for(t = 0; t < num_transverse; t++)
{
if(j + 4 == box_transverse[t] || j + 4 == box_transverse[t] + 1)break;
}
if(t == num_transverse)
{
for(t = 0; t < num_portrait; t++)
{
if(j + 4 == box_portrait[t])break;
}
a = box[int(num_flag)].num_transverse;
// 不是縱塊
if(t == num_portrait)
{
b = box[int(num_flag)].num_portrait;
c = ( mode == 0 ? ( i * num_double[16] + ( j + 4 ) * num_double[8] + k * num_double[0] ) : ( i * num_double[16] + k * num_double[8] + ( j + 4 ) * num_double[0] ) );
}
// 是
else
{
b = box[int(num_flag)].num_portrait - 4 * num_double[t * 5];
c = ( mode == 0 ? ( i * num_double[16] + ( j + 8 ) * num_double[8] + k * num_double[0] ) : ( i * num_double[16] + k * num_double[8] + ( j + 8 ) * num_double[0] ) );
}
check(a, b, c);
}
}
// 左(不是大塊,不是另一個空格,不在最左測,不是縱塊)
if(j - 1 != i + 5 && j - 1 != i + 1 && j - 1 != k && j % 4 != 0)
{
for(t = 0; t < num_portrait; t++)
{
if(j - 1 == box_portrait[t] || j - 1 == box_portrait[t] + 4)break;
}
if(t == num_portrait)
{
for(t = 0; t < num_transverse; t++)
{
if(j - 1 == box_transverse[t] + 1)break;
}
b = box[int(num_flag)].num_portrait;
// 不是橫塊
if(t == num_transverse)
{
a = box[int(num_flag)].num_transverse;
c = ( mode == 0 ? ( i * num_double[16] + ( j - 1 ) * num_double[8] + k * num_double[0] ) : ( i * num_double[16] + k * num_double[8] + ( j - 1 ) * num_double[0] ) );
}
// 是橫塊
else
{
a = box[int(num_flag)].num_transverse + 1 * num_double[t * 5];
c = ( mode == 0 ? ( i * num_double[16] + ( j - 2 ) * num_double[8] + k * num_double[0] ) : ( i * num_double[16] + k * num_double[8] + ( j - 2 ) * num_double[0] ) );
}
check(a, b, c);
}
}
// 右(不是大塊,不是另一個空格,不在最右測,不是縱塊)
if(j + 1 != i && j + 1 != i + 4 && j + 1 != k && j % 4 != 3)
{
for(t = 0; t < num_portrait; t++)
{
if(j + 1 == box_portrait[t] || j + 1 == box_portrait[t] + 4)break;
}
if(t == num_portrait)
{
for(t = 0; t < num_transverse; t++)
{
if(j + 1 == box_transverse[t])break;
}
b = box[int(num_flag)].num_portrait;
// 不是橫塊
if(t == num_transverse)
{
a = box[int(num_flag)].num_transverse;
c = ( mode == 0 ? ( i * num_double[16] + ( j + 1 ) * num_double[8] + k * num_double[0] ) : ( i * num_double[16] + k * num_double[8] + ( j + 1 ) * num_double[0] ) );
}
// 是橫塊
else
{
a = box[int(num_flag)].num_transverse - 1 * num_double[t * 5];
c = ( mode == 0 ? ( i * num_double[16] + ( j + 2 ) * num_double[8] + k * num_double[0] ) : ( i * num_double[16] + k * num_double[8] + ( j + 2 ) * num_double[0] ) );
}
check(a, b, c);
}
}
}
// 雙空格移動函數(shù)
void Gary::double_space()
{
int i, j, k, t, a, b, c;
// 讀取
i = box_big;
j = box_space[0];
k = box_space[1];
// 大格移動
// 上
if(i > 3 && ( ( i - 4 == k && i - 3 == j ) || ( i - 4 == j && i - 3 == k ) ))
{
a = box[int(num_flag)].num_transverse;
b = box[int(num_flag)].num_portrait;
c = ( i - 4 ) * num_double[16] + ( j + 8 ) * num_double[8] + ( k + 8 ) * num_double[0];
check(a, b, c);
}
// 下
if(i < 12 && ( ( i + 8 == k && i + 9 == j ) || ( i + 8 == j && i + 9 == k ) ))
{
a = box[int(num_flag)].num_transverse;
b = box[int(num_flag)].num_portrait;
c = ( i + 4 ) * num_double[16] + ( j - 8 ) * num_double[8] + ( k - 8 ) * num_double[0];
check(a, b, c);
}
// 左
if(i % 4 > 0 && ( ( i - 1 == k && i + 3 == j ) || ( i - 1 == j && i + 3 == k ) ))
{
a = box[int(num_flag)].num_transverse;
b = box[int(num_flag)].num_portrait;
c = ( i - 1 ) * num_double[16] + ( j + 2 ) * num_double[8] + ( k + 2 ) * num_double[0];
check(a, b, c);
}
// 右
if(i % 4 < 2 && ( ( i + 2 == k && i + 6 == j ) || ( i + 2 == j && i + 6 == k ) ))
{
a = box[int(num_flag)].num_transverse;
b = box[int(num_flag)].num_portrait;
c = ( i + 1 ) * num_double[16] + ( j - 2 ) * num_double[8] + ( k - 2 ) * num_double[0];
check(a, b, c);
}
// 橫塊
for(t = 0; t < num_transverse; t++)
{
i = box_transverse[t];
// 上
if(i > 3 && ( ( i - 4 == k && i - 3 == j ) || ( i - 4 == j && i - 3 == k ) ))
{
a = box[int(num_flag)].num_transverse - 4 * num_double[t * 5];
b = box[int(num_flag)].num_portrait;
c = box_big * num_double[16] + ( j + 4 ) * num_double[8] + ( k + 4 ) * num_double[0];
check(a, b, c);
}
// 下
if(i < 16 && ( ( i + 4 == k && i + 5 == j ) || ( i + 4 == j && i + 5 == k ) ))
{
a = box[int(num_flag)].num_transverse + 4 * num_double[t * 5];
b = box[int(num_flag)].num_portrait;
c = box_big * num_double[16] + ( j - 4 ) * num_double[8] + ( k - 4 ) * num_double[0];
check(a, b, c);
}
}
// 縱塊
for(t = 0; t < num_portrait; t++)
{
i = box_portrait[t];
// 左
if(i % 4 > 0 && ( ( i - 1 == k && i + 3 == j ) || ( i - 1 == j && i + 3 == k ) ))
{
a = box[int(num_flag)].num_transverse;
b = box[int(num_flag)].num_portrait - 1 * num_double[t * 5];
c = box_big * num_double[16] + ( j + 1 ) * num_double[8] + ( k + 1 ) * num_double[0];
check(a, b, c);
}
// 右
if(i % 4 < 3 && ( ( i + 1 == k && i + 5 == j ) || ( i + 1 == j && i + 5 == k ) ))
{
a = box[int(num_flag)].num_transverse;
b = box[int(num_flag)].num_portrait + 1 * num_double[t * 5];
c = box_big * num_double[16] + ( j - 1 ) * num_double[8] + ( k - 1 ) * num_double[0];
check(a, b, c);
}
}
}
// 結(jié)束判斷函數(shù)
void Gary::over()
{
// 大格移動至求解終點參數(shù)
if(( box[int(num_flag)].num_other & 0xff0000 ) / num_double[16] == num_over || num_flag1 < num_flag)
{
num_start = 1;
}
}
// 編碼函數(shù)
void Gary::code()
{
int i, j, k;
// 解碼
decode();
// 橫塊排序
for(i = 0; i < num_transverse - 1; i++)
{
for(j = num_transverse - 1; j > i; j--)
{
if(box_transverse[j] > box_transverse[j - 1])
{
k = box_transverse[j];
box_transverse[j] = box_transverse[j - 1];
box_transverse[j - 1] = k;
}
}
}
// 縱塊排序
for(i = 0; i < num_portrait - 1; i++)
{
for(j = num_portrait - 1; j > i; j--)
{
if(box_portrait[j] > box_portrait[j - 1])
{
k = box_portrait[j];
box_portrait[j] = box_portrait[j - 1];
box_portrait[j - 1] = k;
}
}
}
// 空格排序
if(box_space[0] > box_space[1])
{
k = box_space[0];
box_space[0] = box_space[1];
box_space[1] = k;
}
// 編碼
box[int(num_flag)].num_transverse = 0;
box[int(num_flag)].num_portrait = 0;
for(i = 0; i < 6; i++)
{
box[int(num_flag)].num_transverse += box_transverse[i] * num_double[i * 5];
box[int(num_flag)].num_portrait += box_portrait[i] * num_double[i * 5];
}
box[int(num_flag)].num_other = box_big * num_double[16] + box_space[0] * num_double[8] + box_space[1] * num_double[0];
}
// 生成函數(shù)
void Gary::create()
{
// 棋盤初狀態(tài)儲存
// 橫向
box[0].num_transverse = 0;
// 縱向
box[0].num_portrait = 0;
// 標(biāo)準(zhǔn)棋盤
// 棋盤參數(shù)
switch(num_mod)
{
case 0:
{
// 大格
box_big = 1;
// 橫格
box_transverse[0] = 9;
num_transverse = 1;
// 縱格
box_portrait[0] = 0;
box_portrait[1] = 3;
box_portrait[2] = 8;
box_portrait[3] = 11;
num_portrait = 4;
// 空格
box_space[0] = 17;
box_space[1] = 18;
break;
}
case 1:
{
// 大格
box_big = 1;
// 橫格
box_transverse[0] = 9;
num_transverse = 1;
// 縱格
box_portrait[0] = 0;
box_portrait[1] = 3;
box_portrait[2] = 12;
box_portrait[3] = 15;
num_portrait = 4;
// 空格
box_space[0] = 17;
box_space[1] = 18;
break;
}
case 2:
{
// 大格
box_big = 1;
// 橫格
box_transverse[0] = 9;
num_transverse = 1;
// 縱格
box_portrait[0] = 0;
box_portrait[1] = 8;
box_portrait[2] = 13;
box_portrait[3] = 14;
num_portrait = 4;
// 空格
box_space[0] = 16;
box_space[1] = 19;
break;
}
case 3:
{
// 大格
box_big = 1;
// 橫格
box_transverse[0] = 13;
num_transverse = 1;
// 縱格
box_portrait[0] = 0;
box_portrait[1] = 3;
box_portrait[2] = 12;
box_portrait[3] = 15;
num_portrait = 4;
// 空格
box_space[0] = 17;
box_space[1] = 18;
break;
}
case 4:
{
// 大格
box_big = 1;
// 橫格
box_transverse[0] = 17;
num_transverse = 1;
// 縱格
box_portrait[0] = 0;
box_portrait[1] = 3;
box_portrait[2] = 9;
box_portrait[3] = 10;
num_portrait = 4;
// 空格
box_space[0] = 8;
box_space[1] = 11;
break;
}
case 5:
{
// 大格
box_big = 1;
// 橫格
box_transverse[0] = 9;
num_transverse = 1;
// 縱格
box_portrait[0] = 8;
box_portrait[1] = 11;
box_portrait[2] = 13;
box_portrait[3] = 14;
num_portrait = 4;
// 空格
box_space[0] = 16;
box_space[1] = 19;
break;
}
case 6:
{
// 大格
box_big = 1;
// 橫格
box_transverse[0] = 10;
num_transverse = 1;
// 縱格
box_portrait[0] = 0;
box_portrait[1] = 3;
box_portrait[2] = 12;
box_portrait[3] = 13;
num_portrait = 4;
// 空格
box_space[0] = 18;
box_space[1] = 19;
break;
}
case 7:
{
// 大格
box_big = 1;
// 橫格
box_transverse[0] = 9;
num_transverse = 1;
// 縱格
box_portrait[0] = 4;
box_portrait[1] = 7;
box_portrait[2] = 12;
box_portrait[3] = 15;
num_portrait = 4;
// 空格
box_space[0] = 17;
box_space[1] = 18;
break;
}
case 8:
{
// 大格
box_big = 0;
// 橫格
box_transverse[0] = 8;
num_transverse = 1;
// 縱格
box_portrait[0] = 2;
box_portrait[1] = 3;
box_portrait[2] = 12;
box_portrait[3] = 13;
num_portrait = 4;
// 空格
box_space[0] = 18;
box_space[1] = 19;
break;
}
case 9:
{
// 大格
box_big = 5;
// 橫格
box_transverse[0] = 13;
num_transverse = 1;
// 縱格
box_portrait[0] = 0;
box_portrait[1] = 3;
box_portrait[2] = 8;
box_portrait[3] = 11;
num_portrait = 4;
// 空格
box_space[0] = 18;
box_space[1] = 19;
break;
}
case 10:
{
// 大格
box_big = 5;
// 橫格
box_transverse[0] = 1;
num_transverse = 1;
// 縱格
box_portrait[0] = 12;
box_portrait[1] = 13;
box_portrait[2] = 14;
box_portrait[3] = 15;
num_portrait = 4;
// 空格
box_space[0] = 0;
box_space[1] = 3;
break;
}
case 11:
{
// 大格
box_big = 5;
// 橫格
box_transverse[0] = 13;
num_transverse = 1;
// 縱格
box_portrait[0] = 0;
box_portrait[1] = 3;
box_portrait[2] = 11;
box_portrait[3] = 12;
num_portrait = 4;
// 空格
box_space[0] = 17;
box_space[1] = 18;
break;
}
default:break;
}
int i, j, k, t;
// 隨機棋盤
if(num_mod == 12)
{
// 初始化
for(i = 0; i < 20; i++)
{
pan[i] = 0;
}
// 大格生成
box_big = rand() % 3;
pan[box_big] = 1;
pan[box_big + 1] = 5;
pan[box_big + 4] = 6;
pan[box_big + 5] = 7;
// 橫塊生成
i = rand() % 2 + 2;
k = 19;
for(j = 0; j < i; j++)
{
while(k > 18 || k % 4 > 2 || pan[k] != 0 || pan[k + 1] != 0)
{
k = rand() % 19;
}
box_transverse[j] = k;
pan[k] = 2;
pan[k + 1] = 8;
}
num_transverse = i;
// 縱塊生成
t = rand() % 2 + 1;
k = 19;
for(j = 0; j < t; j++)
{
while(k > 15 || k / 4 > 3 || pan[k] != 0 || pan[k + 4] != 0)
{
k = rand() % 16;
}
box_portrait[j] = k;
pan[k] = 3;
pan[k + 4] = 9;
}
num_portrait = t;
// 空格生成
box_space[0] = 17;
while(pan[box_space[0]] != 0)
{
box_space[0] = rand() % 20;
}
pan[box_space[0]] = 4;
// 空格
box_space[1] = 18;
while(pan[box_space[1]] != 0)
{
box_space[1] = rand() % 20;
}
pan[box_space[1]] = 4;
// 小塊生成
for(k = 0; k < 20; k++)
{
if(pan[k] == 4) { pan[k] = 0; }
else if(pan[k] == 0) { pan[k] = 4; }
}
}
// 編碼
for(i = 0; i < 6; i++)
{
box[0].num_transverse += box_transverse[i] * num_double[i * 5];
box[0].num_portrait += box_portrait[i] * num_double[i * 5];
}
box[0].num_other = box_big * num_double[16] + box_space[0] * num_double[8] + box_space[1] * num_double[0];
box[0].num_father = -1;
// 求解鏈初始化
eat[0].num_transverse = box[0].num_transverse;
eat[0].num_portrait = box[0].num_portrait;
eat[0].num_other = box[0].num_other;
}
// 求解函數(shù)
void Gary::solve()
{
int i, j, k;
// 進度條繪制
setlinecolor(RGB(155, 195, 230));
setfillcolor(RGB(73, 130, 120));
fillroundrect(50, 640, 400, 650, 20, 20);
FlushBatchDraw();
// 初始化
box[0].num_transverse = eat[num_eat].num_transverse;
box[0].num_portrait = eat[num_eat].num_portrait;
box[0].num_other = eat[num_eat].num_other;
// 參數(shù)初始化
num_step = 0;
num_flag = 0;
num_flag1 = 1;
// 編碼
code();
num_start = 0;
while(num_start == 0)
{
// 解碼
decode();
// 兩情況大類
// 雙空格移動
double_space();
// 單空格移動
single_space(0);
single_space(1);
// 標(biāo)記數(shù)加一
num_flag++;
// 編碼
code();
// 結(jié)束判斷函數(shù)
over();
// 隨機盤面無解判斷
if(num_flag >= num_flag1 || ( num_mod == 12 && ( num_flag1 > 100000 || num_step > 100 ) ))
{
num_start = 2;
exit_move = 1;
}
}
// 統(tǒng)計步數(shù)
k = 0;
for(i = int(num_flag); box[i].num_father >= 0; i = box[i].num_father)
{
k++;
}
j = k;
// 解題過程錄入
for(i = int(num_flag); k > 0; i = box[i].num_father)
{
eat[num_eat + k].num_transverse = box[i].num_transverse;
eat[num_eat + k].num_portrait = box[i].num_portrait;
eat[num_eat + k].num_other = box[i].num_other;
k--;
}
// 求解鏈長度參數(shù)更新
num_eat += j;
}
// 初始化函數(shù)
void Gary::initialization()
{
int i, j;
// 隨機種子初始化
srand((unsigned)time(NULL));
// 自動解題參數(shù)初始化
num_start = 0;
// 系數(shù)初始化
j = 1;
for(i = 0; i < 31; i++)
{
num_double[i] = j;
j *= 2;
}
// 游戲模式初始化
num_mod = 0;
// 繪制相關(guān)初始化
// 空格繪制
img_space = new IMAGE(100, 100);
// 初始化處理區(qū)域
SetWorkingImage(img_space);
setbkcolor(RGB(73, 130, 120));
cleardevice();
// 繪制
setfillcolor(RGB(112, 180, 167));
solidroundrect(0 + 5, 0 + 5, 100 - 5, 100 - 5, 30, 30);
SetWorkingImage();
// 橫塊繪制
img_transverse = new IMAGE(200, 100);
// 初始化處理區(qū)域
SetWorkingImage(img_transverse);
setbkcolor(RGB(73, 130, 120));
cleardevice();
// 繪制
setfillcolor(RGB(174, 213, 111));
solidroundrect(0, 0, 200, 100, 30, 30);
setfillcolor(RGB(221, 245, 164));
solidroundrect(5, 0, 195, 80, 20, 20);
setfillcolor(RGB(152, 201, 95));
solidroundrect(5, 80, 195, 100, 20, 20);
setfillcolor(RGB(188, 242, 122));
solidroundrect(5, 6, 189, 79, 15, 15);
setfillcolor(RGB(153, 203, 96));
solidcircle(22, 16, 4);
solidcircle(178, 16, 4);
solidcircle(22, 65, 4);
solidcircle(178, 65, 4);
SetWorkingImage();
// 縱塊繪制
img_portrait = new IMAGE(100, 200);
// 初始化處理區(qū)域
SetWorkingImage(img_portrait);
setbkcolor(RGB(73, 130, 120));
cleardevice();
// 繪制
setfillcolor(RGB(75, 113, 179));
solidroundrect(0, 0, 100, 200, 30, 30);
setfillcolor(RGB(153, 188, 247));
solidroundrect(5, 0, 95, 180, 20, 20);
setfillcolor(RGB(64, 96, 151));
solidroundrect(5, 180, 95, 200, 20, 20);
setfillcolor(RGB(99, 147, 231));
solidroundrect(5, 6, 89, 179, 15, 15);
setfillcolor(RGB(73, 111, 180));
solidcircle(22, 16, 4);
solidcircle(78, 16, 4);
solidcircle(22, 165, 4);
solidcircle(78, 165, 4);
SetWorkingImage();
// 小塊繪制
img_small = new IMAGE(100, 100);
// 初始化處理區(qū)域
SetWorkingImage(img_small);
setbkcolor(RGB(73, 130, 120));
cleardevice();
// 繪制
setfillcolor(RGB(208, 174, 47));
solidroundrect(0, 0, 100, 100, 30, 30);
setfillcolor(RGB(254, 234, 158));
solidroundrect(5, 0, 95, 80, 20, 20);
setfillcolor(RGB(186, 145, 38));
solidroundrect(5, 80, 95, 100, 20, 20);
setfillcolor(RGB(254, 217, 81));
solidroundrect(5, 6, 89, 79, 15, 15);
setfillcolor(RGB(202, 168, 43));
solidcircle(22, 16, 4);
solidcircle(78, 16, 4);
solidcircle(22, 65, 4);
solidcircle(78, 65, 4);
SetWorkingImage();
// 大塊繪制
img_big = new IMAGE(200, 200);
// 初始化處理區(qū)域
SetWorkingImage(img_big);
setbkcolor(RGB(73, 130, 120));
cleardevice();
// 繪制
setfillcolor(RGB(215, 102, 65));
solidroundrect(0, 0, 200, 200, 30, 30);
setfillcolor(RGB(254, 195, 166));
solidroundrect(5, 0, 195, 180, 20, 20);
setfillcolor(RGB(194, 98, 62));
solidroundrect(5, 180, 195, 200, 20, 20);
setfillcolor(RGB(252, 153, 108));
solidroundrect(5, 6, 189, 179, 15, 15);
setfillcolor(RGB(210, 100, 60));
solidcircle(22, 16, 4);
solidcircle(178, 16, 4);
solidcircle(22, 165, 4);
solidcircle(178, 165, 4);
POINT pts[20];
setfillcolor(RGB(254, 195, 166));
setlinecolor(RGB(254, 195, 166));
pts[0].x = 100; pts[0].y = 125;
pts[1].x = 125; pts[1].y = 100;
pts[2].x = 150; pts[2].y = 100;
pts[3].x = 100; pts[3].y = 150;
pts[4].x = 50; pts[4].y = 100;
pts[5].x = 75; pts[5].y = 100;
// 繪制
fillpolygon(pts, 6);
pts[0].x = 100; pts[0].y = 125 - 60;
pts[1].x = 125; pts[1].y = 100 - 60;
pts[2].x = 150; pts[2].y = 100 - 60;
pts[3].x = 100; pts[3].y = 150 - 60;
pts[4].x = 50; pts[4].y = 100 - 60;
pts[5].x = 75; pts[5].y = 100 - 60;
// 繪制
fillpolygon(pts, 6);
SetWorkingImage();
// 按鈕初始化
for(i = 0; i < 12; i++)
{
box_button[i].posx1 = 458 + i % 2 * 70;
box_button[i].posy1 = 40 + i / 2 * 100;
box_button[i].posx2 = 508 + i % 2 * 70;
box_button[i].posy2 = 90 + i / 2 * 100;
}
// 棋盤初始化
create();
// 棋盤初始化
for(i = 0; i < 20; i++)
{
switch(pan[i])
{
case 1: {pan[i + 1] = 5; pan[i + 4] = 6; pan[i + 5] = 7; break; }
case 2: {pan[i + 1] = 8; break; }
case 3: {pan[i + 4] = 9; break; }
default:break;
}
}
// 繪制初始
draw_scene(0);
}
// 游戲函數(shù)
void Gary::game()
{
int i, j, k;
// 點哪個格子了
i = ( m.y - 25 ) / 102 * 4 + ( m.x - 25 ) / 102;
// 非空格子
if(pan[i] > 0)
{
// 標(biāo)記
setfillcolor(WHITE);
solidcircle(25 + 51 + i % 4 * 102, 25 + 51 + i / 4 * 102, 5);
FlushBatchDraw();
// 分類討論整理
switch(pan[i])
{
case 5: {i = i - 1; break; }
case 6: {i = i - 4; break; }
case 7: {i = i - 5; break; }
case 8: {i = i - 1; break; }
case 9: {i = i - 4; break; }
default:break;
}
// 又移動到哪個空格子了
k = 0;
while(k == 0)
{
// 鼠標(biāo)信息
if(peekmessage(&m, EM_MOUSE | EM_KEY))
{
// 左鍵單擊判斷
if(m.message == WM_LBUTTONDOWN)
{
// 單擊在棋盤范圍
if(m.x > 20 && m.x < 433 && m.y>15 && m.y < 540)
{
j = ( m.y - 25 ) / 102 * 4 + ( m.x - 25 ) / 102;
if(pan[j] == 0)
{
k = 1;
}
else
{
k = 2;
}
}
}
else if(m.message == WM_MOUSEMOVE)
{
// 單擊在棋盤范圍
if(m.x > 20 && m.x < 433 && m.y>15 && m.y < 540)
{
j = ( m.y - 25 ) / 102 * 4 + ( m.x - 25 ) / 102;
if(pan[j] == 0)
{
k = 1;
}
}
}
}
}
// 點擊空格時分類討論
if(k == 1)
{
switch(pan[i])
{
// 大格
case 1:
{
// 上
if(( j == i - 3 || j == i - 4 ) && pan[i - 4] == 0 && pan[i - 3] == 0 && i / 4 > 0)
{
pan[i - 4] = 1;
pan[i + 4] = 0;
pan[i + 5] = 0;
}
// 下
else if(( j == i + 8 || j == i + 9 ) && pan[i + 8] == 0 && pan[i + 9] == 0 && i / 4 < 3)
{
pan[i + 4] = 1;
pan[i] = 0;
pan[i + 1] = 0;
}
// 左
else if(( j == i - 1 || j == i + 3 ) && pan[i - 1] == 0 && pan[i + 3] == 0 && i % 4 > 0)
{
pan[i - 1] = 1;
pan[i + 1] = 0;
pan[i + 5] = 0;
}
// 右
else if(( j == i + 2 || j == i + 6 ) && pan[i + 2] == 0 && pan[i + 6] == 0 && i % 4 < 2)
{
pan[i + 1] = 1;
pan[i] = 0;
pan[i + 4] = 0;
}
break;
}
// 橫格
case 2:
{
// 上
if(( j == i - 3 || j == i - 4 ) && pan[i - 4] == 0 && pan[i - 3] == 0 && i / 4 > 0)
{
pan[i - 4] = 2;
pan[i] = 0;
pan[i + 1] = 0;
}
// 下
else if(( j == i + 4 || j == i + 5 ) && pan[i + 4] == 0 && pan[i + 5] == 0 && i / 4 < 4)
{
pan[i + 4] = 2;
pan[i] = 0;
pan[i + 1] = 0;
}
// 左
else if(j == i - 1 && pan[i - 1] == 0 && i % 4 > 0)
{
pan[i - 1] = 2;
pan[i + 1] = 0;
}
// 右
else if(j == i + 2 && pan[i + 2] == 0 && i % 4 < 2)
{
pan[i + 1] = 2;
pan[i] = 0;
}
break;
}
// 縱格
case 3:
{
// 上
if(j == i - 4 && pan[i - 4] == 0 && i / 4 > 0)
{
pan[i - 4] = 3;
pan[i + 4] = 0;
}
// 下
else if(j == i + 8 && pan[i + 8] == 0 && i / 4 < 3)
{
pan[i + 4] = 3;
pan[i] = 0;
}
// 左
else if(( j == i - 1 || j == i + 3 ) && pan[i - 1] == 0 && pan[i + 3] == 0 && i % 4 > 0)
{
pan[i - 1] = 3;
pan[i] = 0;
pan[i + 4] = 0;
}
// 右
else if(( j == i + 1 || j == i + 5 ) && pan[i + 1] == 0 && pan[i + 5] == 0 && i % 4 < 3)
{
pan[i + 1] = 3;
pan[i] = 0;
pan[i + 4] = 0;
}
break;
}
case 4: {if(( j == i - 4 && i / 4 > 0 ) || ( j == i - 1 && i % 4 > 0 ) || ( j == i + 1 && i % 4 < 3 ) || ( j == i + 4 && i / 4 < 4 )) { pan[j] = 4; pan[i] = 0; }break; }
default:break;
}
// 棋盤標(biāo)準(zhǔn)化
for(i = 0; i < 20; i++)
{
switch(pan[i])
{
case 1: {pan[i + 1] = 5; pan[i + 4] = 6; pan[i + 5] = 7; break; }
case 2: {pan[i + 1] = 8; break; }
case 3: {pan[i + 4] = 9; break; }
default:break;
}
}
}
// 繪制
// 背景繪制
setbkcolor(RGB(136, 192, 160));
cleardevice();
// 棋盤繪制
setfillcolor(RGB(73, 130, 120));
setlinecolor(RGB(168, 226, 195));
fillroundrect(20, 15, 25 + 102 * 4, 30 + 102 * 5, 30, 30);
for(i = 0; i < 20; i++)
{
switch(pan[i])
{
case 0:putimage(25 + i % 4 * 102, 25 + i / 4 * 102, img_space); break;
case 1:putimage(25 + i % 4 * 102, 25 + i / 4 * 102, img_big); break;
case 2:putimage(25 + i % 4 * 102, 25 + i / 4 * 102, img_transverse); break;
case 3:putimage(25 + i % 4 * 102, 25 + i / 4 * 102, img_portrait); break;
case 4:putimage(25 + i % 4 * 102, 25 + i / 4 * 102, img_small); break;
default:break;
}
// 出口繪制
if(pan[i] == 0 && ( i == 13 || i == 14 || i == 17 || i == 18 ))
{
setlinecolor(RGB(230, 230, 230));
setlinestyle(PS_SOLID, 10);
setfillcolor(RGB(112, 180, 167));
fillcircle(25 + 51 + i % 4 * 102, 25 + 51 + i / 4 * 102, 20);
setlinecolor(RGB(168, 226, 195));
setfillcolor(RGB(73, 130, 120));
setlinestyle(PS_SOLID, 3);
}
}
// 按鈕繪制
TCHAR s[25];
setlinecolor(RGB(155, 195, 230));
setfillcolor(RGB(80, 189, 222));
settextcolor(RGB(230, 230, 230));
settextstyle(30, 20, _T("Times New Roman"));
setbkcolor(RGB(80, 189, 222));
// 標(biāo)準(zhǔn)棋盤按鈕
for(i = 0; i < 12; i++)
{
fillroundrect(box_button[i].posx1, box_button[i].posy1, box_button[i].posx2, box_button[i].posy2, 20, 20);
_stprintf_s(s, _T("%d"), i);
outtextxy(box_button[i].posx1 + 13 - 12 * ( i / 10 ), box_button[i].posy1 + 10, s);
}
// 其他按鈕
settextstyle(100, 100, _T("Webdings"));
settextcolor(RGB(73, 130, 120));
setbkmode(TRANSPARENT);
outtextxy(102 - 50, 580 - 30, 0x34); // 播放,求解
outtextxy(214 - 50, 580 - 30, 0x33); // 重置,恢復(fù)初始盤面
outtextxy(326 - 50, 580 - 30, 0x71); // 刷新,隨機盤面按鈕
// 恢復(fù)填充
setbkmode(OPAQUE);
setbkmode(OPAQUE);
settextcolor(RGB(230, 230, 230));
settextstyle(30, 20, _T("宋體"));
setbkcolor(RGB(136, 192, 160));
outtextxy(102 - 50, 655, _T("求解"));
outtextxy(214 - 50, 655, _T("恢復(fù)"));
outtextxy(326 - 50, 655, _T("刷新"));
FlushBatchDraw();
// 成功結(jié)束
if(pan[13] == 1)
{
exit_move = 2;
}
}
}
// 窗口主視角函數(shù),獲取用戶操作
void Gary::move()
{
int k;
exit_move = 0;
while(exit_move == 0)
{
// 鼠標(biāo)信息
if(peekmessage(&m, EM_MOUSE | EM_KEY))
{
// 左鍵單擊判斷
if(m.message == WM_LBUTTONDOWN)
{
// 單擊在棋盤范圍
if(m.x > 20 && m.x < 433 && m.y>15 && m.y < 540)
{
// 游戲函數(shù)
game();
}
// 經(jīng)典盤面按鈕
else if(m.x > 458)
{
// 切換
num_mod = ( m.x - 458 ) / 70 + ( m.y - 40 ) / 100 * 2;
// 生成
create();
// 繪制
draw_scene(0);
}
// 演示按鈕
else if(pow(double(m.x - 102), 2) + pow(double(m.y - 600), 2) < 2500)
{
// 初始化
num_eat = 0;
if(num_mod == 9 || num_mod == 11)
{
num_over = 8;
}
else
{
num_over = 9;
}
solve();
num_over = 13;
solve();
if(exit_move == 0)
{
// 繪制解題過程
for(k = 0; k <= num_eat; k++)
{
// 根據(jù)特征值畫棋面
draw_scene(k);
Sleep(500);
}
}
}
// 重置按鈕
else if(pow(double(m.x - 214), 2) + pow(double(m.y - 600), 2) < 2500)
{
// 根據(jù)特征值畫棋面
draw_scene(0);
FlushBatchDraw();
}
// 刷新按鈕
else if(pow(double(m.x - 326), 2) + pow(double(m.y - 600), 2) < 2500)
{
// 切換
num_mod = 12;
// 生成
create();
// 繪制
draw_scene(0);
}
// 清空鼠標(biāo)隊列
flushmessage();
}
}
}
// 結(jié)束提示
if(exit_move == 2)
{
MessageBox(hOut, _T("成功啦,點擊確定即刷新"), _T("來自小豆子的提醒"), MB_OK);
}
else if(exit_move == 1)
{
MessageBox(hOut, _T("無解,點擊確定即刷新"), _T("來自小豆子的提醒"), MB_OK);
}
}
// 主進程
void Gary::carry()
{
// 窗口定義
hOut = initgraph(600, 102 * 5 + 200);
SetWindowText(hOut, _T("華容道"));
// 進程控制
exit_carry = 0;
BeginBatchDraw();
while(exit_carry == 0)
{
initialization();
move();
}
EndBatchDraw();
closegraph();
}
// 主函數(shù)
int main(void)
{
Gary G;
G.carry();
return 0;
}到此這篇關(guān)于基于C語言自制華容道游戲的示例代碼的文章就介紹到這了,更多相關(guān)C語言華容道游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中sln,vcxproj,vcxproj.filters,lib,dll,exe的含義說明
這篇文章主要介紹了C++中sln,vcxproj,vcxproj.filters,lib,dll,exe的含義說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05
C++ COM編程之QueryInterface函數(shù)(一)
這篇文章主要介紹了C++ COM編程之QueryInterface函數(shù)(一),QueryInterface是組件本身提供對自己查詢的一個接口,需要的朋友可以參考下2014-10-10

