<!-- .slide: data-background="https://freight.cargo.site/w/1920/q/94/i/028e19f0688320543e922d6c29bdd25cef76e4aac244d2762faba0cb500b764f/MAT_LYF_CHANGE_01.gif" -->
# :video_game:**數字益智遊戲**:video_game:
<br></br>
#### ***Number Puzzle Game***
##### 第2組
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
### 組員 :dolls: :
- 朱浿晴 D0766525 :girl: :grin:
- 林興隆 D0708837 :boy: :innocent:
- 雷國亮 D0726433 :boy: :sunglasses:
- 陳聖樺 D0781530 :girl: :laughing:
- 洪琪紡 D0792475 :girl: :grinning:
- 李文灝 D0892357 :boy: :smile:
---
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
# :bulb: **概念** :bulb:
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
數字益智遊戲是一種旨在按正確順序排列每個數字的遊戲。正方形的大小為 N x N,並且數字範圍最大為 N^2^ - 1。例如,如果正方形的大小是 3 x 3,那麼數字範圍將是1到8,因為它將空出一個空格來移動數字。
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
## 當號碼排列不正確 :x:
***

----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
## 當數字已經正確排列 :white_check_mark:
***

---
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
# :art: **設計說明** :art:
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
* 如須選擇選項,可輸入編號或輸入文字
* 可以根據自身喜好選擇背景顏色
* 遊戲獲勝,會有動畫跳出
* 遊戲開始為隨機亂數排列
---
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
# :page_with_curl: **代碼結構** :page_with_curl:
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
:one: 移動數字方塊
```cpp=
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <conio.h>
const int x = 5, y = 5; // puzzle陣列的最大儲量空間
// 移動數字方塊
int moving(int puzzle[y][x], int n, int gap_y, int gap_x) {
int key;
switch (key = _getch()) {
case 224:
switch (key = _getch()) {
case 72: // 數字向上移
if (gap_y < n - 1) {
puzzle[gap_y][gap_x] = puzzle[gap_y + 1][gap_x];
puzzle[gap_y + 1][gap_x] = 0;
return 1;
}
break;
case 80: // 數字向下移
if (gap_y > 0) {
puzzle[gap_y][gap_x] = puzzle[gap_y - 1][gap_x];
puzzle[gap_y - 1][gap_x] = 0;
return 1;
}
break;
case 75: // 數字向左移
if (gap_x < n - 1) {
puzzle[gap_y][gap_x] = puzzle[gap_y][gap_x + 1];
puzzle[gap_y][gap_x + 1] = 0;
return 1;
}
break;
case 77: // 數字向右移
if (gap_x > 0) {
puzzle[gap_y][gap_x] = puzzle[gap_y][gap_x - 1];
puzzle[gap_y][gap_x - 1] = 0;
return 1;
}
break;
default:
break;
}
break;
case 27: // ESC鍵終止程式
exit(0);
default:
printf("Invalid Input! Only use Arrow Keys!\n");
system("pause");
break;
}
return 0;
}
```
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
:two: 檢驗puzzle是否有解
```cpp=
int verify_puzzle(int puzzle[y][x], int n) {
int order[x*y];
int num = 0, reverse = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
order[num] = puzzle[i][j]; // 將puzzle從二維轉換到一維陣列
num++;
}
}
for (int i = 0; i < n*n - 2; i++) {
for (int j = i + 1; j < n*n - 1; j++) {
if (order[i] > order[j]) reverse++; // 計算puzzle內, 逆序的總和
}
}
return reverse % 2; // 偶數有解, 奇數則無解
}
```
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
:three: 調亂puzzle方塊
```cpp=
void setup_puzzle(int puzzle[y][x], int n) {
srand(time(NULL));
int rand_y, rand_x, temp;
while (1) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == n - 1 && j == n - 1) break; // 缺口不用掉換
rand_y = rand() % n;
rand_x = rand() % n;
if (rand_y == n - 1 && rand_x == n - 1) continue; // 排除與缺口掉換的可能
temp = puzzle[i][j];
puzzle[i][j] = puzzle[rand_y][rand_x];
puzzle[rand_y][rand_x] = temp;
}
}
if (!verify_puzzle(puzzle, n)) break;
}
}
```
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
:four: 顯示方框
```cpp=
void display(int puzzle[y][x], int n) {
int k = 0;
for (int i = 0; i < n * 2 + 1; i++) {
if (i % 2 == 0) { // 印出線框
for (int j = 0; j < n * 4 + 1; j++) {
if (i == 0 && j == 0) printf("┌");
else if (i == n * 2 && j == 0) printf("└");
else if (i > 0 && j == 0) printf("├");
else if (i == 0 && j == n * 4) printf("┐");
else if (i == n * 2 && j == n * 4) printf("┘");
else if (i > 0 && j == n * 4) printf("┤");
else if (i == 0 && j > 0 && j % 4 == 0) printf("┬");
else if (i == n * 2 && j > 0 && j % 4 == 0) printf("┴");
else if (i > 0 && j > 0 && j % 4 == 0) printf("┼");
else printf("─");
}
printf(" \n");
}
else { // 印出數字
for (int j = 0; j < n; j++) {
if (puzzle[k][j] == 0) printf("│ ");
else printf("│ %02d", puzzle[k][j]);
if (j == n - 1) printf("│");
}
printf(" \n");
k++;
}
}
}
```
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
:five: 改變背景色彩
```cpp=
void col(int n) {
if (n == 0) system("COLOR 07");
else if (n == 1) system("COLOR B0");
else if (n == 2) system("COLOR A0");
else if (n == 3) system("COLOR C7");
else if (n == 4) system("COLOR D7");
else if (n == 5) system("COLOR E0");
else if (n == 6) system("COLOR F0");
}
```
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
:six: 顯示動畫
```cpp=
void animation() { //~(˘▾˘~) ~(˘▾˘)~ (~˘▾˘)~
int i;
for (i = 0; i < 3; i++) {
system("cls");
printf("____ ** /\\ /\\ ____ **\n");
printf(" | ** / \\ / \\ | **\n");
printf(" | ** | **\n");
printf(" |___** \\ / |___**\n");
printf(" ** -- **\n");
printf(" ~GOOD JOB~ \n");
printf(" 好棒喔! ");
Sleep(200);
system("cls");
printf("____ ** /\\ /\\ ** ____\n");
printf(" | ** / \\ / \\ ** |\n");
printf(" | ** _____ ** |\n");
printf(" |___** | | **___|\n");
printf(" ** |___| **\n");
printf(" ~GOOD JOB~ \n");
printf(" 好棒喔! ");
Sleep(200);
system("cls");
printf(" ** ____ /\\ /\\ ** ____\n");
printf(" ** | / \\ / \\ ** |\n");
printf("** | ** |\n");
printf(" **___| | | **___|\n");
printf(" ** |___| **\n");
printf(" ~GOOD JOB~ \n");
printf(" 好棒喔! ");
Sleep(200);
}
system("cls");
}
```
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
:seven: 主函式
```cpp=
int main() {
int puzzle[y][x];
char color, level;
int size;
while (1) {
system("cls");
printf("Choose any color you like!\n");
printf("0. Default \n1. Aqua \n2. Green \n3. Red \n4. Purple \n5. Yellow \n6. White\n>Number: ");
scanf("%c", &color);
color = color - 48;
if (color < 0 || color > 6) continue;
else if (color >= 0 || color <= 6) col(color);
system("cls");
while (2) {
system("cls");
printf("Choose any level you want!\n");
printf("1. REGULAR [3X3]\n"
"2. MEDIUM [4X4]\n"
"3. EXTREME [5X5]\n>");
scanf("%c", &level);
level = level - 48;
if (level < 1 || level > 3) continue;
else if (level >= 1 || level <= 3) {
if (level == 1) size = 3;
else if (level == 2) size = 4;
else if (level == 3) size = 5;
break;
}
}
// 初始化, puzzle的賦值
int num = 1;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
puzzle[i][j] = num;
if (num == size * size) puzzle[i][j] = 0;
num++;
}
}
setup_puzzle(puzzle, size);
// 開始遊玩
int gap_y, gap_x;
size_t steps = 0;
while (1) {
system("cls");
display(puzzle, size);
printf("Steps: %d\n", steps);
// 檢驗是否完成
num = 0;
int complete = 1;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i == size - 1 && j == size - 1) num = 0;
else num++;
if (puzzle[i][j] != num) complete = 0;
}
}
if (complete) {
printf("YOU WIN!\n\n");
animation();
char play;
while (1) {
printf("Play again?(Y/N) ");
while (getchar() != '\n');
scanf("%c", &play);
if (play == 'Y' || play == 'y') {
system("cls");
break;
}
else if (play == 'N' || play == 'n') {
exit(0);
}
else {
printf("Invalid Input\n");
continue;
}
}
break;
}
// 找出缺口位置
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (puzzle[i][j] == 0) {
gap_y = i;
gap_x = j;
}
}
}
if (moving(puzzle, size, gap_y, gap_x)) steps++;
}
}
return 0;
}
```
---
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
# :game_die: **使用方法** :game_die:
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
| Command | Description |
|:------------:|:------------------------:|
| 輸入數字 | 選擇顏色跟level |
| 鍵盤方向鍵 | 將圖塊移到空白處 |
| 輸入 Y/N | 選擇是否繼續玩 |
---
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
# :rainbow: **程式特色** :rainbow:
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
- 有7種背景顏色可供選擇
- 難易度分為三個level, 有(3X3)、(4X4)、(5X5)
- 贏得遊戲後, 會有小小的動畫來慶祝你的勝利
---
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
## :cry:**想做但尚未實做的功能**:cry:
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
* 我們打算要做loading的特效,可是我們不知道如何要設計
* 想要做scoreboard但不行
* 原本想要由玩家自訂size,但失敗了
* 想要放圖片,也想讓輸出的字體大小更大,並與cmd窗口成比例
---
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
## :wrench: **開發環境與套件** :wrench:
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
僅限於Windows環境
IDE:Code::Blocks
Library:<stdio.h>、<stdlib.h>、<time.h>、<string.h>、<conio.h>
---
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
## :construction: **遇到的困難與解決方法** :construction:
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
我們原來是打算要箭頭方向移動, 但發現有問題. 還有那個線框只有在台灣的電腦可以打開,可惜在其他國家的電腦不能打開
---
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
## :notebook_with_decorative_cover: **開發小記和心得** :notebook_with_decorative_cover:
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
## **開發小記**
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
**2019/12/19**
* 討論要做怎麼樣的應用程式
**2019/12/20**
* 概念製作
**2019/12/26**
* 加了play again但還有一點錯
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
**2019/12/27**
* 我們增加函數讓那個程式看起來比較好看
**2019/12/28**
* 加了註解,並修改了play again問題
**2019/12/29**
* 增加顏色,可是我只給一個顏色
* 修改指向缺口
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
**2019/12/31**
* 增加很多顏色的選擇也加了level選擇
**2020/01/01**
* 有修改如果我按其他的按鈕, 那個steps不會計算
**2019/01/02**
* 方向鍵已修正, 註解了哪一些部分是由誰參與編寫
----
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
## **開發心得**
#### 大家一開始毫無頭緒,接著提出很多遊戲的想法,最後決定要做puzzle game。因為我們起步得太晚,所以只要有人ㄧ有問題提出來,我們都會盡力去幫助。在編碼的過程中,我們原先設定的是讓玩家能夠自訂方塊的尺寸,不過經過多次測試後,我們發現自己只能做出數字比較小的尺寸,因此我們決定改成只有3個級別。雖然在中間過程中程式碼有很多要修正的地方,可是借助大家的力量,我們都一ㄧ克服了,所以這個成品出來後,我們都很感動。我要謝謝組員們的幫助,因為有他們才有這個作品,你們真的太棒了!
---
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
## :tada: **作者與工作分配** :checkered_flag:
----
<!--這裡有問題-->
<!--我不知道怎麼了,但是名稱格式應該合併,在系統關閉後,名稱格式不正確-->
<!--林興隆-->
<!--名字應該是這樣的-->
<!--林興
隆-->
<!--不是這樣-->
<!--| 成員 | 負責工作 |
|:--------:|:----------:|
| 朱浿晴 |基本游戲的程式|
| 林興隆 |增加一個顏色、修改缺口的問題
| 雷國亮 |編碼錯誤修復和改進、HackMD設計|
| 陳聖樺 | 繼續遊戲或結束、除錯、編輯HackMD|
| 洪琪紡 |顏色跟level的選擇、小小動畫|
| 李文灝 | 移動方塊、檢驗是否有解、調亂方塊、顯示方框|-->
成員 | 負責工作
##### - 朱浿晴 D0766525 | 基本游戲的程式
##### - 林興隆 D0708837 | 增加一個顏色、修改缺口的問題
##### - 雷國亮 D0726433 | 編碼錯誤修復和改進、HackMD設計&動畫
##### - 陳聖樺 D0781530 | 繼續遊戲或結束、除錯、編輯HackMD
##### - 洪琪紡 D0792475 | 顏色跟level的選擇、程式小小動畫
##### - 李文灝 D0892357 | 移動方塊、檢驗是否有解、調亂方塊、顯示方框
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
---
<!-- .slide: data-background="https://www.thiagopetherson.tech/img/base-background.png" data-background-color="#005" -->
# :telescope: **使用資源** :bookmark:
code::blocks、HackMD
---
<!-- .slide: data-background="https://freight.cargo.site/w/1920/q/94/i/e86f09ffcc2139a5bde8808e647ab70ea7eb02a5001b252e72a628d314e0c802/Thank-you.gif" -->
<br></br>
<br></br>
### 謝謝!
###### 第2組
---
###### tags: `第2組` `期末專題` `小遊戲`
{"metaMigratedAt":"2023-06-15T02:43:50.752Z","metaMigratedFrom":"YAML","title":"The Number Puzzle Game","breaks":true,"slideOptions":"{\"transition\":\"slide\"}","contributors":"[{\"id\":null,\"add\":6611,\"del\":1751},{\"id\":\"befaa4d9-75b6-4c05-baa7-7949e0ffa1e2\",\"add\":9371,\"del\":3165},{\"id\":\"ce4b4ffd-ae29-4d03-b588-87441674a126\",\"add\":3595,\"del\":1863},{\"id\":\"d743044f-0783-44e9-9ffa-fcc95125dd6c\",\"add\":7,\"del\":22},{\"id\":\"72fc9d17-7547-4d86-ad99-ff037fb961dc\",\"add\":1618,\"del\":62}]"}