# FSM 有限狀態機參考程式碼 ## C++ :::spoiler **提示** ```cpp= #include <iostream> using namespace std; int main() { string name; cout << "FSM Example"<< endl << endl; int state = 0; //起始狀態 int input; //輸入 while(1) { switch(state) { case 0://狀態 0:閒晃 cout << "Current State : Wander"<< endl; cout << "Input Option : 0.Player Nearby" << endl; cout << "Input : "; cin >> input; //讀取輸入 if(input == 0) { state = 10; //狀態變換 } break; case 10://狀態 10:攻擊 cout << "Current State : Attack"<< endl; cout << "Input Option : 0.Player Out Of Sight 1.Player Fight Back" << endl; cout << "Input : "; cin >> input; if(input == 0) { state = 0; } else if(input == 1) { state = 20; } break; case 20://狀態 20:撤退 cout << "Current State : Evade"<< endl; cout << "Input Option : 0.Health are Low 1.Player is Idle" << endl; cout << "Input : "; cin >> input; //TO_DO break; case 30://狀態 30:尋找補品 cout << "Current State : Find Aid"<< endl; cout << "Input Option : 0.Get Aid" << endl; cout << "Input : "; cin >> input; if(input == 0) { state = //TO_DO } break; } cout << endl; } } ``` ::: :::spoiler **參考答案** ```cpp= #include <iostream> using namespace std; int main() { string name; cout << "FSM Example"<< endl << endl; int state = 0; //起始狀態 int input; //輸入 while(1) { switch(state) { case 0://狀態 0:閒晃 cout << "Current State : Wander"<< endl; cout << "Input Option : 0.Player Nearby" << endl; cout << "Input : "; cin >> input; //讀取輸入 if(input == 0) { state = 10; //狀態變換 } break; case 10://狀態 10:攻擊 cout << "Current State : Attack"<< endl; cout << "Input Option : 0.Player Out Of Sight 1.Player Fight Back" << endl; cout << "Input : "; cin >> input; if(input == 0) { state = 0; } else if(input == 1) { state = 20; } break; case 20://狀態 20:撤退 cout << "Current State : Evade"<< endl; cout << "Input Option : 0.Health are Low 1.Player is Idle" << endl; cout << "Input : "; cin >> input; if(input == 0) { state = 30; } else if(input == 1) { state = 10; } break; case 30://狀態 30:尋找補品 cout << "Current State : Find Aid"<< endl; cout << "Input Option : 0.Get Aid" << endl; cout << "Input : "; cin >> input; if(input == 0) { state = 0; } break; } cout << endl; } } ``` ::: ## Arduino ### **燈泡&按鈕 1** :::spoiler **提示** ```cpp= #include <LedControl.h> #define CIN 6 #define CS 7 #define CLK 8 #define Button 2 #define Width 8 #define Height 8 LedControl LC = LedControl(CIN,CLK,CS,1); void Update(int Map[Height][Width]) // LED 更新函式 { for(int i=0;i<Height;i++) { for(int j=0;j<Width;j++) { bool temp; if(Map[i][j]==0) { temp=false; } else { temp=true; } LC.setLed(0,j,i,Map[7-i][j]); } } } int On[8][8]={{0,0,0,0,0,0,0,0}, {0,0,0,0,1,0,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,1,1,1,0,0}, {0,1,1,1,0,1,1,1}, {0,0,0,1,1,1,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,0,1,0,0,0}}; int state = 0; void setup() { pinMode(CIN,OUTPUT); pinMode(CS,OUTPUT); pinMode(CLK,OUTPUT); pinMode(Button,INPUT); LC.shutdown(0,false); LC.setIntensity(0,15);//(0~15) LC.clearDisplay(0); Serial.begin(9600); } void loop() { Serial.println(state); switch (state) { case 0://燈泡暗 LC.clearDisplay(0); //TO_DO break; case 1://燈泡亮 Update(On); //TO_DO break; } } ``` ::: :::spoiler **參考答案** ```cpp= #include <LedControl.h> #define CIN 6 #define CS 7 #define CLK 8 #define Button 2 #define Width 8 #define Height 8 LedControl LC = LedControl(CIN,CLK,CS,1); void Update(int Map[Height][Width]) { for(int i=0;i<Height;i++) { for(int j=0;j<Width;j++) { bool temp; if(Map[i][j]==0) { temp=false; } else { temp=true; } LC.setLed(0,j,i,Map[7-i][j]); } } } int On[8][8]={{0,0,0,0,0,0,0,0}, {0,0,0,0,1,0,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,1,1,1,0,0}, {0,1,1,1,0,1,1,1}, {0,0,0,1,1,1,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,0,1,0,0,0}}; int state = 0; void setup() { pinMode(CIN,OUTPUT); pinMode(CS,OUTPUT); pinMode(CLK,OUTPUT); pinMode(Button,INPUT); LC.shutdown(0,false); LC.setIntensity(0,15);//(0~15) LC.clearDisplay(0); Serial.begin(9600); } void loop() { Serial.println(state); switch (state) { case 0://燈泡暗 LC.clearDisplay(0); if(digitalRead(Button) == HIGH) { state = 1; } break; case 1://燈泡亮 Update(On); if(digitalRead(Button) == LOW) { state = 0; } break; } } ``` ::: ### **燈泡&按鈕 2** :::spoiler **提示** ```cpp= #include <LedControl.h> #define CIN 6 #define CS 7 #define CLK 8 #define Button 2 #define Width 8 #define Height 8 LedControl LC = LedControl(CIN,CLK,CS,1); void Update(int Map[Height][Width]) { for(int i=0;i<Height;i++) { for(int j=0;j<Width;j++) { bool temp; if(Map[i][j]==0) { temp=false; } else { temp=true; } LC.setLed(0,j,i,Map[7-i][j]); } } } int On[8][8]={{0,0,0,0,0,0,0,0}, {0,0,0,0,1,0,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,1,1,1,0,0}, {0,1,1,1,0,1,1,1}, {0,0,0,1,1,1,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,0,1,0,0,0}}; int state = 0; void setup() { pinMode(CIN,OUTPUT); pinMode(CS,OUTPUT); pinMode(CLK,OUTPUT); pinMode(Button,INPUT); LC.shutdown(0,false); LC.setIntensity(0,10);//(0~15) LC.clearDisplay(0); //Update(On); Serial.begin(9600); } void loop() { Serial.println(state); switch (state) { case 0: //燈暗 按鈕放 LC.clearDisplay(0); if(digitalRead(Button) == //TO_DO) { state = //TO_DO; } break; case 1: //燈暗 按鈕押 if(digitalRead(Button) == //TO_DO) { state = //TO_DO; } break; case 2: //燈亮 按鈕放 Update(On); if(digitalRead(Button) == //TO_DO) { state = //TO_DO; } break; case 3: //燈亮 按鈕押 if(digitalRead(Button) == //TO_DO) { state = //TO_DO; } break; } } ``` ::: :::spoiler **參考答案** ```cpp= #include <LedControl.h> #define CIN 6 #define CS 7 #define CLK 8 #define Button 2 #define Width 8 #define Height 8 LedControl LC = LedControl(CIN,CLK,CS,1); void Update(int Map[Height][Width]) { for(int i=0;i<Height;i++) { for(int j=0;j<Width;j++) { bool temp; if(Map[i][j]==0) { temp=false; } else { temp=true; } LC.setLed(0,j,i,Map[7-i][j]); } } } int On[8][8]={{0,0,0,0,0,0,0,0}, {0,0,0,0,1,0,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,1,1,1,0,0}, {0,1,1,1,0,1,1,1}, {0,0,0,1,1,1,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,0,1,0,0,0}}; int state = 0; void setup() { pinMode(CIN,OUTPUT); pinMode(CS,OUTPUT); pinMode(CLK,OUTPUT); pinMode(Button,INPUT); LC.shutdown(0,false); LC.setIntensity(0,10);//(0~15) LC.clearDisplay(0); //Update(On); Serial.begin(9600); } void loop() { Serial.println(state); switch (state) { case 0: //燈暗 按鈕放 LC.clearDisplay(0); if(digitalRead(Button) == HIGH) { state = 1; } break; case 1: //燈暗 按鈕押 if(digitalRead(Button) == LOW) { state = 2; } break; case 2: //燈亮 按鈕放 Update(On); if(digitalRead(Button) == HIGH) { state = 3; } break; case 3: //燈亮 按鈕押 if(digitalRead(Button) == LOW) { state = 0; } break; } } ``` ::: ### **燈泡閃爍-delay** :::spoiler **參考答案** ```cpp= #include <LedControl.h> #define CIN 6 #define CS 7 #define CLK 8 #define Button 2 #define Width 8 #define Height 8 LedControl LC = LedControl(CIN,CLK,CS,1); void Update(int Map[Height][Width]) { for(int i=0;i<Height;i++) { for(int j=0;j<Width;j++) { bool temp; if(Map[i][j]==0) { temp=false; } else { temp=true; } LC.setLed(0,j,i,Map[7-i][j]); } } } int On[8][8]={{0,0,0,0,0,0,0,0}, {0,0,0,0,1,0,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,1,1,1,0,0}, {0,1,1,1,0,1,1,1}, {0,0,0,1,1,1,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,0,1,0,0,0}}; int state = 0; void setup() { pinMode(CIN,OUTPUT); pinMode(CS,OUTPUT); pinMode(CLK,OUTPUT); pinMode(Button,INPUT); LC.shutdown(0,false); LC.setIntensity(0,10);//(0~15) LC.clearDisplay(0); //Update(On); Serial.begin(9600); } void loop() { Serial.println(state); switch (state) { case 0: LC.clearDisplay(0); if(digitalRead(Button) == HIGH) { state = 1; } break; case 1: if(digitalRead(Button) == LOW) { state = 2; } break; case 2: Update(On); if(digitalRead(Button) == HIGH) { state = 3; } break; case 3: if(digitalRead(Button) == LOW) { state = 4; } break; case 4: Update(On); delay(500); LC.clearDisplay(0); delay(500); if(digitalRead(Button) == HIGH) { state = 5; } break; case 5: if(digitalRead(Button) == LOW) { state = 0; } break; } } ``` ::: ### **自定義物件 Timer** :::spoiler **程式碼** ```cpp= class Timer { private: long Time; public: void TimerShutdown() { Time = -1; } void TimerSet() { Time = millis(); } bool TimerTimeout(long Millis) { long C_Time = millis(); if ((C_Time - Time) < Millis || Time == -1) { return false; } else { return true; } } }; ``` ::: ### **燈泡閃爍 - Timer** :::spoiler **參考答案** ```cpp= #include <LedControl.h> #define CIN 6 #define CS 7 #define CLK 8 #define Button 2 #define Width 8 #define Height 8 class Timer { private: long Time; public: void TimerShutdown() { Time = -1; } void TimerSet() { Time = millis(); } bool TimerTimeout(long Millis) { long C_Time = millis(); if ((C_Time - Time) < Millis || Time == -1) { return false; } else { return true; } } }; LedControl LC = LedControl(CIN,CLK,CS,1); Timer Timer1;//宣告物件 void Update(int Map[Height][Width]) { for(int i=0;i<Height;i++) { for(int j=0;j<Width;j++) { bool temp; if(Map[i][j]==0) { temp=false; } else { temp=true; } LC.setLed(0,j,i,Map[7-i][j]); } } } int On[8][8]={{0,0,0,0,0,0,0,0}, {0,0,0,0,1,0,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,1,1,1,0,0}, {0,1,1,1,0,1,1,1}, {0,0,0,1,1,1,0,0}, {0,0,1,0,1,0,1,0}, {0,0,0,0,1,0,0,0}}; int Flag = 0; int state = 0; void setup() { pinMode(CIN,OUTPUT); pinMode(CS,OUTPUT); pinMode(CLK,OUTPUT); pinMode(Button,INPUT); LC.shutdown(0,false); LC.setIntensity(0,10);//(0~15) LC.clearDisplay(0); Timer1.TimerShutdown(); Serial.begin(9600); } void loop() { Serial.println(state); switch (state) { case 0: LC.clearDisplay(0); if(digitalRead(Button) == HIGH) { state = 1; } break; case 1: if(digitalRead(Button) == LOW) { state = 2; } break; case 2: Update(On); if(digitalRead(Button) == HIGH) { state = 3; } break; case 3: if(digitalRead(Button) == LOW) { state = 4; Timer1.TimerSet();//開始計時 } break; case 4: if(Flag == 0 && Timer1.TimerTimeout(500))// { LC.clearDisplay(0); Timer1.TimerSet(); Flag =1; } else if(Flag == 1 && Timer1.TimerTimeout(500)) { Update(On); Timer1.TimerSet(); Flag =0; } if(digitalRead(Button) == HIGH) { state = 5; } break; case 5: if(digitalRead(Button) == LOW) { state = 0; } break; } } ``` ::: ### **簡易飲水機** :::spoiler **提示** ```cpp= #include <LedControl.h> #define Cold 2 #define Warm 3 #define Cont 4 #define DIN 6 #define CS 7 #define CLK 8 int state = 0; int flag = 0; class Timer { private: long Time; public: void TimerShutdown() { Time = -1; } void TimerSet() { Time = millis(); } bool TimerTimeout(long Millis) { long C_Time = millis(); if ((C_Time - Time) < Millis || Time == -1) { return false; } else { return true; } } }; int C[8][8] = { {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 1, 0, 0}, {0, 1, 1, 0, 0, 1, 1, 0}, {0, 1, 1, 0, 0, 0, 0, 0}, {0, 1, 1, 0, 0, 0, 0, 0}, {0, 1, 1, 0, 0, 0, 0, 0}, {0, 1, 1, 0, 0, 1, 1, 0}, {0, 0, 1, 1, 1, 1, 0, 0} }; int W[8][8] = { {0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 1, 0, 0, 0, 1, 1}, {0, 1, 1, 0, 0, 0, 1, 1}, {0, 1, 1, 0, 0, 0, 1, 1}, {0, 1, 1, 0, 1, 0, 1, 1}, {0, 1, 1, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 0, 1, 1, 1}, {0, 1, 1, 0, 0, 0, 1, 1} }; int cont[8][8] = { {0, 0, 1, 1, 1, 1, 0, 0}, {0, 1, 1, 1, 1, 1, 1, 0}, {1, 1, 1, 0, 0, 1, 1, 1}, {1, 1, 0, 0, 0, 0, 1, 1}, {1, 1, 0, 0, 0, 0, 1, 1}, {1, 1, 1, 0, 0, 1, 1, 1}, {0, 1, 1, 1, 1, 1, 1, 0}, {0, 0, 1, 1, 1, 1, 0, 0} }; LedControl LC = LedControl(DIN, CLK, CS, 1); Timer Timer1; void Update(int Map[8][8]) { for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { bool temp; if (Map[i][j] == 0) { temp = false; } else { temp = true; } LC.setLed(0, j, 7 - i, temp); //Serial.print(Map[i][j]); } //Serial.println(); } } void setup() { pinMode(DIN, OUTPUT); pinMode(CS, OUTPUT); pinMode(CLK, OUTPUT); pinMode(Cold, INPUT); pinMode(Warm, INPUT); pinMode(Cont, INPUT); LC.shutdown(0, false); LC.setIntensity(0, 1); //(0~15) Serial.begin(9600); } void loop() { Serial.println(state); switch (state) { //TO_DO } } ``` ::: :::spoiler **參考答案** ```cpp= #include <LedControl.h> #define Cold 2 #define Warm 3 #define Cont 4 #define DIN 6 #define CS 7 #define CLK 8 int state = 0; int flag = 0; class Timer { private: long Time; public: void TimerShutdown() { Time = -1; } void TimerSet() { Time = millis(); } bool TimerTimeout(long Millis) { long C_Time = millis(); if ((C_Time - Time) < Millis || Time == -1) { return false; } else { return true; } } }; int C[8][8] = { {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 1, 0, 0}, {0, 1, 1, 0, 0, 1, 1, 0}, {0, 1, 1, 0, 0, 0, 0, 0}, {0, 1, 1, 0, 0, 0, 0, 0}, {0, 1, 1, 0, 0, 0, 0, 0}, {0, 1, 1, 0, 0, 1, 1, 0}, {0, 0, 1, 1, 1, 1, 0, 0} }; int W[8][8] = { {0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 1, 0, 0, 0, 1, 1}, {0, 1, 1, 0, 0, 0, 1, 1}, {0, 1, 1, 0, 0, 0, 1, 1}, {0, 1, 1, 0, 1, 0, 1, 1}, {0, 1, 1, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 0, 1, 1, 1}, {0, 1, 1, 0, 0, 0, 1, 1} }; int cont[8][8] = { {0, 0, 1, 1, 1, 1, 0, 0}, {0, 1, 1, 1, 1, 1, 1, 0}, {1, 1, 1, 0, 0, 1, 1, 1}, {1, 1, 0, 0, 0, 0, 1, 1}, {1, 1, 0, 0, 0, 0, 1, 1}, {1, 1, 1, 0, 0, 1, 1, 1}, {0, 1, 1, 1, 1, 1, 1, 0}, {0, 0, 1, 1, 1, 1, 0, 0} }; LedControl LC = LedControl(DIN, CLK, CS, 1); Timer Timer1; void Update(int Map[8][8]) { for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { bool temp; if (Map[i][j] == 0) { temp = false; } else { temp = true; } LC.setLed(0, j, 7 - i, temp); //Serial.print(Map[i][j]); } //Serial.println(); } } void setup() { pinMode(DIN, OUTPUT); pinMode(CS, OUTPUT); pinMode(CLK, OUTPUT); pinMode(Cold, INPUT); pinMode(Warm, INPUT); pinMode(Cont, INPUT); LC.shutdown(0, false); LC.setIntensity(0, 1); //(0~15) Serial.begin(9600); } void loop() { Serial.println(state); switch (state) { case 0: LC.clearDisplay(0); if (digitalRead(Cold) == HIGH) { state = 10; } else if (digitalRead(Warm) == HIGH) { state = 20; } else if (digitalRead(Cont) == HIGH) { state = 30; Timer1.TimerSet(); } break; case 10: //冷水暫時出水 Update(C); if (digitalRead(Cold) == LOW) { state = 0; } break; case 20://Warm Water Temporary Update(W); if (digitalRead(Warm) == LOW) { state = 0; } break; case 30: if (digitalRead(Cont) == LOW) { state = 31; } break; case 31: if (Timer1.TimerTimeout(250)) { if (flag == 1) { flag = 0; Update(cont); } else { LC.clearDisplay(0); flag = 1; } Timer1.TimerSet(); } if (digitalRead(Cont) == HIGH) { state = 32; } else if (digitalRead(Cold) == HIGH) { state = 40; } else if (digitalRead(Warm) == HIGH) { state = 50; } break; case 32: if (digitalRead(Cont) == LOW) { state = 0; } break; case 40: if (digitalRead(Cold) == LOW) { state = 41; } break; case 41: Update(C); if (digitalRead(Cold) == HIGH) { state = 42; } else if(digitalRead(Cont) == HIGH) { state = 32; } break; case 42: if (digitalRead(Cold) == LOW) { state = 0; } break; case 50: if (digitalRead(Warm) == LOW) { state = 51; } break; case 51: Update(W); if (digitalRead(Warm) == HIGH) { state = 52; } else if(digitalRead(Cont) == HIGH) { state = 32; } break; case 52: if (digitalRead(Warm) == LOW) { state = 0; } break; } } ``` ::: ## 俄羅斯方塊遊戲機 :::spoiler **程式碼** ```cpp= #include <LedControl.h> #define INI_speed 500 //初始速度 單位ms //腳位定義 #define Rotate 2 #define Right 3 #define Left 4 #define Down 5 #define CIN 6 #define CS 7 #define CLK 8 //長寬 #define Width 8 #define Height 10 class Timer { private: long Time; public: void TimerShutdown() { Time = -1; } void TimerSet() { Time = millis(); } bool TimerTimeout(long Millis) { long C_Time = millis(); if ((C_Time - Time) < Millis || Time == -1) { return false; } else { return true; } } }; /*方塊種類定義 | | 0 | 1 | 2 ___|___|___ | | 3 |4&9| 5 ___|___|___ | | 6 | 7 | 8 | | */ //Blocktype[方塊種類][選轉次數][補正碼] int Blocktype[7][4][4] = { {{3, 4, 5, 4}, {1, 4, 7, 4}, {3, 4, 5, 4}, {1, 4, 7, 4}}, //0 I {{0, 1, 3, 4}, {0, 1, 3, 4}, {0, 1, 3, 4}, {0, 1, 3, 4}}, //1 O {{1, 3, 4, 5}, {1, 4, 5, 7}, {3, 4, 5, 7}, {1, 3, 4, 7}}, //2 T {{1, 2, 3, 4}, {1, 4, 5, 8}, {4, 5, 6, 7}, {0, 3, 4, 7}}, //3 S {{0, 1, 4, 5}, {2, 4, 5, 7}, {3, 4, 7, 8}, {1, 3, 4, 6}}, //4 Z {{0, 3, 4, 5}, {1, 2, 4, 7}, {3, 4, 5, 8}, {1, 4, 6, 7}}, //5 J {{2, 3, 4, 5}, {1, 4, 7, 8}, {3, 4, 5, 6}, {0, 1, 4, 7}} //6 L }; /* 補正碼 以4為中心x、y的相對位置 */ int x_c[9] = { -1, 0, 1, -1, 0, 1, -1, 0, 1}; int y_c[9] = { -1, -1, -1, 0, 0, 0, 1, 1, 1}; int gravity = INI_speed; //重力(掉落速度) int state = -1; //狀態 int T_map[Height][Width]; //地圖矩陣 int C_block = -1; //目前方塊種類 int C_rotate = 0; //目前旋轉狀態 int C_pos[2]; //目前方塊4號位置 0->y , 1->x; int score = 0; //分數 bool legit = true; //檢測動作是否合法 Timer Timer1[10]; LedControl LC = LedControl(CIN, CLK, CS, 1); //LED矩陣物件 /* 左上角為原點 向右為+ 向下為+ */ void Update(int Map[Height][Width]) { for (int i = 2; i < Height; i++) { for (int j = 0; j < Width; j++) { bool temp; if (Map[i][j] == 0) { temp = false; } else { temp = true; } LC.setLed(0, j, 9 - i, temp); //Serial.print(Map[i][j]); } //Serial.println(); } } void C_Rotate(int nextstate) { legit = true; int New_rotate = (C_rotate + 1) % 4; for (int i = 0; i < 4; i++) { int n = Blocktype[C_block][New_rotate][i]; int new_x = C_pos[1] + x_c[n]; int new_y = C_pos[0] + y_c[n]; if ( T_map[new_y][new_x] == 1 || new_x > 7 || new_x < 0 || new_y >= Height ) { legit = false; break; } } if (legit) { for ( int i = 0 ; i < 4 ; i++ ) { int n = Blocktype[C_block][C_rotate][i]; T_map[C_pos[0] + y_c[n]][C_pos[1] + x_c[n]] = 0; } C_rotate = New_rotate; for (int i = 0; i < 4; i++) { int n = Blocktype[C_block][C_rotate][i]; int new_x = C_pos[1] + x_c[n]; int new_y = C_pos[0] + y_c[n]; T_map[new_y][new_x] = 2; } } state = nextstate; Update(T_map); } void C_Right(int nextstate) { legit = true; for (int i = 0; i < 4; i++) { int n = Blocktype[C_block][C_rotate][i]; int new_x = C_pos[1] + x_c[n] + 1; int new_y = C_pos[0] + y_c[n]; if ( T_map[new_y][new_x] == 1 || new_x > 7 ) { legit = false; break; } } if (legit) { for (int i = 0; i < 4; i++) { int n = Blocktype[C_block][C_rotate][i]; int old_x = C_pos[1] + x_c[n]; int old_y = C_pos[0] + y_c[n]; T_map[old_y][old_x] = 0; } C_pos[1] += 1; for (int i = 0; i < 4; i++) { int n = Blocktype[C_block][C_rotate][i]; int new_x = C_pos[1] + x_c[n]; int new_y = C_pos[0] + y_c[n]; T_map[new_y][new_x] = 2; } } state = nextstate; Update(T_map); } void C_Left(int nextstate) { legit = true; for (int i = 0; i < 4; i++) { int n = Blocktype[C_block][C_rotate][i]; int new_x = C_pos[1] + x_c[n] - 1; int new_y = C_pos[0] + y_c[n]; if (T_map[new_y][new_x] == 1 || new_x < 0) { legit = false; break; } } if (legit) { for (int i = 0; i < 4; i++) { int n = Blocktype[C_block][C_rotate][i]; int old_x = C_pos[1] + x_c[n]; int old_y = C_pos[0] + y_c[n]; T_map[old_y][old_x] = 0; } C_pos[1] -= 1; for (int i = 0; i < 4; i++) { int n = Blocktype[C_block][C_rotate][i]; int new_x = C_pos[1] + x_c[n]; int new_y = C_pos[0] + y_c[n]; T_map[new_y][new_x] = 2; } } state = nextstate; Update(T_map); } void C_Down(int nextstate) { legit = true; for (int i = 0; i < 4; i++) { int n = Blocktype[C_block][C_rotate][i]; int new_x = C_pos[1] + x_c[n]; int new_y = C_pos[0] + y_c[n] + 1; if (T_map[new_y][new_x] == 1 || new_y >= Height) { legit = false; break; } } for (int i = 0; i < 4; i++) { int n = Blocktype[C_block][C_rotate][i]; int old_x = C_pos[1] + x_c[n]; int old_y = C_pos[0] + y_c[n]; if (legit) { T_map[old_y][old_x] = 0; } else { T_map[old_y][old_x] = 1; } } if (legit) { C_pos[0] += 1; for (int i = 0; i < 4; i++) { int n = Blocktype[C_block][C_rotate][i]; int new_x = C_pos[1] + x_c[n]; int new_y = C_pos[0] + y_c[n]; T_map[new_y][new_x] = 2; } state = nextstate; } else { for (int i = 0; i < Height ; i++) { bool check = true; for (int j = 0; j < Width; j++) { if (T_map[i][j] != 1) { check = false; break; } } if (check == false) { continue; } else { score += 10; gravity = INI_speed - score; Update(T_map); delay(10); for (int j = i ; j >= 1 ; j--) { for (int k = 0 ; k < Width ; k++) { T_map[j][k] = T_map[j - 1][k]; } } for (int k = 0 ; k < Width ; k++) { T_map[0][k] = 0; } Update(T_map); } } bool over = false; for (int i = 0; i < Width ; i++) { if (T_map[1][i] == 1) { over = true; break; } } if (over) { for (int i = Height - 1; i >= 1; i--) { for (int j = 0; j < 8; j++) { T_map[i][j] = 0; LC.setLed(0, i - 1, j, false); Update(T_map); } } state = -1; } else { state = 15; } } Timer1[0].TimerSet(); Update(T_map); } void setup() { Serial.begin(9600); //定義接角模式 pinMode(Rotate, INPUT); pinMode(Right, INPUT); pinMode(Left, INPUT); pinMode(Down, INPUT); pinMode(CIN, OUTPUT); pinMode(CS, OUTPUT); pinMode(CLK, OUTPUT); pinMode(A0, INPUT); randomSeed(analogRead(A0)); //產生隨機種子碼,A0空接會取得空氣中電壓,可視為亂碼 C_block = random(7); //LED矩陣開啟 LC.shutdown(0, false); //LED矩陣挑整亮度(0~15) LC.setIntensity(0, 5); for (int i = 0 ; i < 10; i++) //重設所有計時器 { Timer1[i].TimerShutdown(); } //清空地圖 for (int i = 0; i < Height; i++) { for (int j = 0; j < Width; j++) { T_map[i][j] = 0; } } } void loop() { Serial.println(state); switch (state) { case -1://數值初始化 score = 0; gravity = INI_speed; for (int i = 0 ; i < 10; i++) //重設所有計時器 { Timer1[i].TimerShutdown(); } for (int i = 0; i <= 8; i++) { for (int j = 0; j < 8; j++) { T_map[i][j] = 0; } } state = 0; break; case 0: if (digitalRead(Rotate) == HIGH) { state = 10; } break; case 10: if (digitalRead(Rotate) == LOW) { state = 14; } break; case 14: for (int i = 0; i < Height; i++) { for (int j = 0; j < 8; j++) { T_map[i][j] = 0; } state = 15; } break; case 15: //產生隨機方塊 C_block = random(7); C_pos[0] = 1; //y C_pos[1] = 4; //x C_rotate = 0; state = 20; break; case 20: Timer1[0].TimerSet(); state = 25; break; case 25://偵測按鈕 if (digitalRead(Rotate) == HIGH) { Serial.println("rotate"); Timer1[1].TimerSet(); state = 30; } else if (digitalRead(Right) == HIGH) { Serial.println("right"); Timer1[1].TimerSet(); state = 35; } else if (digitalRead(Left) == HIGH) { Serial.println("left"); Timer1[1].TimerSet(); state = 40; } else if (digitalRead(Down) == HIGH) { Serial.println("down"); Timer1[1].TimerSet(); state = 45; } break; case 30://旋轉 if (digitalRead(Rotate) == LOW) { C_Rotate(25); } else if (Timer1[1].TimerTimeout(500)) { Timer1[2].TimerSet(); state = 31; } break; case 31: if (digitalRead(Rotate) == LOW) { C_Rotate(25); } else if (Timer1[2].TimerTimeout(100)) { Timer1[2].TimerSet(); C_Rotate(state); } break; case 35://右移 if (digitalRead(Right) == LOW) { C_Right(25); } else if (Timer1[1].TimerTimeout(500)) { Timer1[2].TimerSet(); state = 36; } break; case 36: if (digitalRead(Right) == LOW) { C_Right(25); } else if (Timer1[2].TimerTimeout(100)) { Timer1[2].TimerSet(); C_Right(state); } break; case 40://左移 if (digitalRead(Left) == LOW) { C_Left(25); } else if (Timer1[1].TimerTimeout(500)) { Timer1[2].TimerSet(); state = 41; } break; case 41: if (digitalRead(Left) == LOW) { C_Left(25); } else if (Timer1[2].TimerTimeout(100)) { Timer1[2].TimerSet(); C_Left(state); } break; case 45://下移 if (digitalRead(Down) == LOW) { C_Down(25); } else if (Timer1[1].TimerTimeout(500)) { Timer1[2].TimerSet(); state = 46; } break; case 46: if (digitalRead(Down) == LOW) { C_Down(25); } else if (Timer1[2].TimerTimeout(100)) { Timer1[2].TimerSet(); C_Down(state); } break; } //Fall down if (Timer1[0].TimerTimeout(gravity)) { C_Down(state); } } ``` :::