自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

鴻蒙基于WiFi IoT套件開發(fā)的猜數(shù)字小游戲代碼分享

系統(tǒng)
猜數(shù)字是一個(gè)很經(jīng)典的小游戲,也是編程開發(fā)入門的典型,以下為基于WiFi IoT套件開發(fā)的猜數(shù)字小游戲的具體開發(fā)過程和效果。

猜數(shù)字是一個(gè)很經(jīng)典的小游戲,也是編程開發(fā)入門的典型,以下為基于WiFi IoT套件開發(fā)的猜數(shù)字小游戲的具體開發(fā)過程和效果。

基本規(guī)則:

由甲方(玩家)默想一個(gè)1-99(包含)內(nèi)的任意數(shù)字(整數(shù)),然后由乙方進(jìn)行猜測,并詢問甲方猜測的數(shù)字是大了還是小了,甲方根據(jù)實(shí)際情況進(jìn)行回復(fù),則乙方最多問6個(gè)問題,就一定能夠猜中甲方默想的數(shù)字。

基本原理:

乙方問最多6次,包括最后一次說出猜中的數(shù)字,實(shí)際上乙方最多有7次猜測的機(jī)會(huì)。

而使用二分進(jìn)行查找,2^7=128,則99以內(nèi)的數(shù)字,完全可以覆蓋,因此乙方絕對(duì)可以猜中。

實(shí)現(xiàn)概述:

以上的基本規(guī)則和基本原理明確了,我們要在WiFi IoT套件上實(shí)現(xiàn),并且甲方需要參與,需要處理以下三個(gè)部分:

  1. 猜數(shù)字的主邏輯
  2. 使用OLED屏幕顯示提示信息,讓玩家進(jìn)行互動(dòng)操作:我們需要在屏幕上顯示漢字,進(jìn)行玩家當(dāng)前猜測的數(shù)字,以及玩家按鍵后告知玩家結(jié)果
  3. 使用按鍵接收玩家操作(大了或者小了等):在這個(gè)實(shí)例中,我們使用了ADC方式來讀取按鍵信息,從而獲得玩家具體操作。所使用的按鍵為核心板上的USR按鍵,和OLED板上的S1,S2按鍵。使用ADC方式讀取的時(shí)候,他們所使用的輸入端口為GPIO5/ADC2,具體的按鍵作用如下:
  • USR:開始游戲,或者確認(rèn)
  • S1:如果猜小了,則玩家按S1告知
  • S2:如果猜大了,則玩家按S2告知

原始代碼修改處理:【代碼基礎(chǔ)為code-1.0.tar.gz】

  • 開啟I2C:vendor/hisi/hi3861/hi3861/build/config/usr_config.mk
  1. ## BSP Settings 
  2. # CONFIG_I2C_SUPPORT is not set 
  3. CONFIG_I2C_SUPPORT=y 
  4. # CONFIG_I2S_SUPPORT is not set​ 
  •  I2C復(fù)用端口設(shè)置:vendor/hisi/hi3861/hi3861/app/wifiiot_app/init/app_io_init.c
  1. #ifdef CONFIG_I2C_SUPPORT 
  2.     /* I2C IO復(fù)用也可以選擇3/4; 9/10,根據(jù)產(chǎn)品設(shè)計(jì)選擇 */ 
  3.     // hi_io_set_func(HI_IO_NAME_GPIO_0, HI_IO_FUNC_GPIO_0_I2C1_SDA); 
  4.     // hi_io_set_func(HI_IO_NAME_GPIO_1, HI_IO_FUNC_GPIO_1_I2C1_SCL); 
  5.     hi_io_set_func(HI_IO_NAME_GPIO_13, HI_IO_FUNC_GPIO_13_I2C0_SDA); 
  6.     hi_io_set_func(HI_IO_NAME_GPIO_14, HI_IO_FUNC_GPIO_14_I2C0_SCL); 
  7. #endif​ 

 主邏輯代碼:guess.c

  1. #include <stdio.h> 
  2. #include <unistd.h> 
  3.  
  4. #include <ohos_init.h> 
  5. #include <cmsis_os2.h> 
  6. #include <hiview_config.h> 
  7. #include <hiview_log.h> 
  8. #include <wifiiot_watchdog.h> 
  9. #include <hi_task.h> 
  10.  
  11. #include "button/button.h" 
  12. #include "oled/oled.h" 
  13.  
  14. /* 
  15. 0123456789 
  16. 請(qǐng)?jiān)谛闹心胍粋€(gè)1~99的整數(shù),我能在6個(gè)問題之內(nèi)猜出這個(gè)數(shù) 
  17. 想好了就按【USER】開始游戲吧,【RST】重啟 
  18. 小了按【S1】,大了按【S2】,正確按【USER】 
  19. 第?個(gè)問題,是這個(gè)數(shù)嗎:?? 
  20. 大了??!那我再猜小一點(diǎn) 
  21. 小了??!那我再猜大一點(diǎn) 
  22. 哈哈,我猜到了吧! 
  23. 按【USER】再玩一次(請(qǐng)先默想一個(gè)1~99的整數(shù)) 
  24. 你默想的數(shù)一定是?? 
  25.  
  26. //  開始:0,長度10 
  27. //  開始:10,長度30 
  28. //  開始:40,長度24 
  29. //  開始:64,長度25 
  30. //  開始:89,長度14 
  31. //  開始:103,長度11 
  32. //  開始:114,長度11 
  33. //  開始:125,長度9 
  34. //  開始:134,長度26 
  35. //  開始:160,長度10 
  36. */ 
  37. char *str[] = { 
  38.     "0123456789"
  39.     "請(qǐng)?jiān)谛闹心胍粋€(gè)1~99的整數(shù),我能在6個(gè)問題之內(nèi)猜出這個(gè)數(shù)"
  40.     "想好了就按【USER】開始游戲吧,【RST】重啟"
  41.     "小了按【S1】,大了按【S2】,正確按【USER】"
  42.     "第?個(gè)問題,是這個(gè)數(shù)嗎:??"
  43.     "大了?。∧俏以俨滦∫稽c(diǎn)"
  44.     "小了?。∧俏以俨麓笠稽c(diǎn)"
  45.     "哈哈,我猜到了吧!"
  46.     "按【USER】再玩一次(請(qǐng)先默想一個(gè)1~99的整數(shù))"
  47.     "你默想的數(shù)一定是??" 
  48. }; 
  49.  
  50. int pos[][2] = { 
  51.     {0, 10}, 
  52.     {10, 30}, 
  53.     {40, 24}, 
  54.     {64, 25}, 
  55.     {89, 14}, 
  56.     {103, 11}, 
  57.     {114, 11}, 
  58.     {125, 9}, 
  59.     {134, 26}, 
  60.     {160, 10} 
  61. }; 
  62.  
  63. void display_string(int idx,int delay,int num1, int num2){ 
  64.     int start=0; 
  65.     int len=0; 
  66.  
  67.     start = pos[idx][0]; 
  68.     len = pos[idx][1]; 
  69.     if(idx==4 && num2==100) { 
  70.         len = len +1; 
  71.     } 
  72.     u8 no[len]; 
  73.     for(int i=0;i<len;i++){ 
  74.         no[i] = start+i; 
  75.     } 
  76.     // 4 "第?個(gè)問題,是這個(gè)數(shù)嗎:??"
  77.     if(idx==4) { 
  78.         no[1] = num1; 
  79.         if(num2==100) { 
  80.             no[len-3] = 1; 
  81.             no[len-2] = 0; 
  82.             no[len-2] = 0; 
  83.         } else { 
  84.             no[len-2] = num2/10; 
  85.             no[len-1] = num2%10; 
  86.         } 
  87.     } 
  88.     OLED_Clear(); 
  89.     OLED_ShowChineseString(0,0,no,len,16);         
  90.     usleep(delay*1000*1000);     
  91.  
  92. // 主任務(wù) 
  93. static void *GuessTask(const char *arg){ 
  94.     (void)arg; 
  95.  
  96.     gpio_button_init(); 
  97.     oled_display_init(); 
  98.  
  99.     OLED_Clear(); 
  100.     printf("請(qǐng)?jiān)谛闹心胍粋€(gè)1~100的整數(shù),我能在6個(gè)問題之內(nèi)猜出這個(gè)數(shù)是什么:\n"); 
  101.     display_string(1,2,0,0); 
  102.     printf("想好了就按【USER】開始游戲吧,【RST】重啟\n"); 
  103.     display_string(2,2,0,0); 
  104.     printf("小了按【S1】,大了按【S2】,正確按【USER】\n"); 
  105.     display_string(3,0,0,0); 
  106.  
  107.     key_event_t zf; //聲明char類型來存放輸入的字符 
  108.     char number; //電腦猜測的數(shù)字 
  109.  
  110.     while ((zf = gpio_button_get())!=KEY_EVENT_NONE) 
  111.     { 
  112.         // getchar();//忽略回車 
  113.         char min_shu = 1;   // 1是初始最小數(shù)。 
  114.         char max_shu = 100; // 100是初始最大數(shù)。 
  115.  
  116.         if (zf == KEY_EVENT_USER) 
  117.         { 
  118.             int jishu = 1; // 計(jì)數(shù)用的,6個(gè)問題以內(nèi)嘛。 
  119.             while (1)   // 條件一直為真,死循環(huán),能用break跳出循環(huán),或用return跳出整個(gè)函數(shù)。 
  120.             { 
  121.                 number = (min_shu + max_shu) / 2; // 最小數(shù)和最大數(shù)的和除2 ,意思就是取它們的中間值。 
  122.                 printf("\n第%d個(gè)問題,是這個(gè)數(shù)嗎:%d", jishu, number); 
  123.                 display_string(4,0,jishu, number); 
  124.                 zf = gpio_button_get(); 
  125.                 // getchar();//忽略回車 
  126.  
  127.                 if (zf == KEY_EVENT_S2) 
  128.                 { 
  129.                     printf("\n大了??!那我再猜小一點(diǎn)\n"); 
  130.                     display_string(5,2,0,0); 
  131.                     max_shu = number - 1; //如果是大了,那最大值至少比目前的數(shù)小1。 
  132.                     jishu++;              //回答次數(shù)加1 ,如果你回答了電腦6次問題,電腦還沒有猜對(duì),那電腦就輸了。 
  133.                 } 
  134.                 if (zf == KEY_EVENT_S1) 
  135.                 { 
  136.                     printf("\n小了??!那我再猜大一點(diǎn)\n"); 
  137.                     display_string(6,2,0,0); 
  138.                     min_shu = number + 1; //如果是小了,那最小值至少比目前的數(shù)大1。 
  139.                     jishu++;              //同上面,計(jì)數(shù)加1 
  140.                 } 
  141.                 if (zf == KEY_EVENT_USER) 
  142.                 { 
  143.                     // printf("y\n"); 
  144.                     printf("\n哈哈,我猜到了吧!\n"); 
  145.                     display_string(7,2,0,0); 
  146.                     printf("按【USER】再玩一次(請(qǐng)?jiān)谛闹邢饶胍粋€(gè)1~100的整數(shù)),【RST】重啟\n"); 
  147.                     display_string(8,0,0,0); 
  148.                     break; 
  149.                 } 
  150.                 if (jishu == 7) 
  151.                 { 
  152.                     printf("\n你默想的數(shù)一定是%d",(min_shu + max_shu) / 2); 
  153.                     display_string(9,2,0,0); 
  154.                     printf("\n按【USER】再玩一次(請(qǐng)?jiān)谛闹邢饶胍粋€(gè)1~100的整數(shù)),【RST】重啟\n"); 
  155.                     display_string(8,0,0,0); 
  156.                     break; 
  157.                 } 
  158.             } 
  159.         } 
  160.         else { 
  161.             printf("\n按鍵無效,請(qǐng)重新選擇(按【USER】開始,【RST】重啟):"); 
  162.         } 
  163.     } 
  164.     return NULL
  165.  
  166. // 程序入口 
  167. static void GuessEntry(void) 
  168.     osThreadAttr_t attr; 
  169.     WatchDogDisable(); 
  170.     SetLogLevel(HILOG_LV_ERROR); 
  171.  
  172.     attr.name = "GuessTask"
  173.     attr.attr_bits = 0U; 
  174.     attr.cb_mem = NULL
  175.     attr.cb_size = 0U; 
  176.     attr.stack_mem = NULL
  177.     attr.stack_size = 1024; 
  178.     attr.priority = osPriorityNormal; 
  179.  
  180.     if (osThreadNew((osThreadFunc_t)GuessTask, NULL, &attr) == NULL) { 
  181.         printf("[GuessNum] Falied to create GuessTask!\n"); 
  182.     } 
  183.  
  184. SYS_RUN(GuessEntry); 

主邏輯代碼說明:

因?yàn)樵贠LED上面顯示字符(包括漢字),需要預(yù)先取得漢字的字模點(diǎn)陣數(shù)據(jù);在這個(gè)實(shí)例中,會(huì)有不同的提示語出現(xiàn),且未中文,為了方便處理,我將每句話的字模點(diǎn)陣數(shù)據(jù)單獨(dú)取出,所以定義了str[],pos[][2],以及display_string(),用于顯示對(duì)應(yīng)的語句。其最終調(diào)用oled/oled.c中的OLED_ShowChineseString()來將漢字輸出到OLED屏幕;特別的,語句4“第?個(gè)問題,是這個(gè)數(shù)嗎:??”需要處理具體數(shù)字,所以進(jìn)行了特殊的處理。

獲取按鍵的部分,在button/button.c中的gpio_button_get(),代碼隨后展示,用于獲取按鍵的狀態(tài)

OLED部分代碼:【以下為oled/oled.h,oled/oled.c和字模數(shù)據(jù)oled/oledfont.h請(qǐng)查看附件】

  1. #ifndef __OLED_H 
  2. #define __OLED_H 
  3.  
  4.  
  5. #define OLED_MODE 0 
  6. #define SIZE 8 
  7. #define XLevelL     0x00 
  8. #define XLevelH     0x10 
  9. #define Max_Column  128 
  10. #define Max_Row     64 
  11. #define Brightness  0xFF  
  12. #define X_WIDTH     128 
  13. #define Y_WIDTH     64       
  14.  
  15.  
  16. #define OLED_CMD  0 //寫命令 
  17. #define OLED_DATA 1 //寫數(shù)據(jù) 
  18.  
  19.  
  20. #define u8 unsigned char 
  21. #define u16 unsigned short 
  22. #define u32 unsigned int 
  23.  
  24. //OLED控制用函數(shù) 
  25. void delay_ms(unsigned int ms); 
  26. void OLED_ColorTurn(u8 i); 
  27. void OLED_DisplayTurn(u8 i); 
  28. void OLED_WR_Byte(u8 dat,u8 cmd); 
  29. void OLED_Set_Pos(u8 x, u8 y); 
  30. void OLED_Display_On(void); 
  31. void OLED_Display_Off(void); 
  32. void OLED_Clear(void); 
  33. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey); 
  34. u32 oled_pow(u8 m,u8 n); 
  35. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 sizey); 
  36. void OLED_ShowString(u8 x,u8 y,char *chr,u8 sizey); 
  37. void OLED_ShowChinese(u8 x,u8 y,u8 no,u8 sizey); 
  38. void OLED_ShowChineseString(u8 x,u8 y,u8 no[],u8 length,u8 sizey); 
  39. void OLED_Direct_ShowString(u8 x,u8 y,char *chr,u8 sizey); 
  40. void OLED_DrawBMP(u8 x,u8 y,u8 sizex, u8 sizey,u8 BMP[]); 
  41. void OLED_Init(void); 
  42. void oled_display_init(void); 
  43. #endif 

 OLED漢字字模數(shù)據(jù)獲取方式:

在OLED上面顯示字符(包括漢字),本質(zhì)上是描點(diǎn),所以獲取對(duì)應(yīng)字符的點(diǎn)陣數(shù)據(jù)即可。

生成字模數(shù)據(jù)的工具為PCToLCD,設(shè)置為字符模式和C51格式;這個(gè)工具還可以用于取圖片的點(diǎn)陣數(shù)據(jù)。

具體獲取方式如下:

按鍵部分代碼:【以下為button/button.h,button/button.c請(qǐng)查看附件】

  1. #ifndef __BUTTON_H 
  2. #define __BUTTON_H 
  3.  
  4. #include <hi_types_base.h> 
  5.  
  6. #define APP_DEMO_ADC 
  7. #define ADC_TEST_LENGTH 64 
  8. #define VLT_MIN 100 
  9. #define STATUS_LEN 4 
  10.  
  11. // 按鍵狀態(tài)定義 
  12. typedef enum 
  13.     KEY_EVENT_NONE = 0, 
  14.     KEY_EVENT_S1, 
  15.     KEY_EVENT_S2, 
  16.     KEY_EVENT_USER 
  17. } key_event_t; 
  18.  
  19. //獲取當(dāng)前按鍵 
  20. key_event_t get_key_event(void); 
  21.  
  22. // ADC轉(zhuǎn)換 
  23. hi_void convert_to_voltage(hi_u32 data_len); 
  24.  
  25. // ADC獲取 
  26. void button_adc_test(void); 
  27.  
  28. // 設(shè)置 按鍵中斷響應(yīng) 
  29. void gpio_button_init(void); 
  30.  
  31. // 獲取需要的按鍵狀態(tài) 
  32. key_event_t gpio_button_get(void); 
  33.  
  34. #endif 

 按鍵部分代碼說明:

當(dāng)使用ADC方式來讀取按鍵狀態(tài)的時(shí)候,本質(zhì)上,是讀取了ADC輸入端口的數(shù)據(jù),這個(gè)數(shù)據(jù)進(jìn)過一定的轉(zhuǎn)換,能夠化為對(duì)應(yīng)的電壓數(shù)據(jù)。而不同的按鍵按下后,ADC端口讀取的電壓是不同的,并且是在一定范圍內(nèi)波動(dòng)的,對(duì)應(yīng)按鍵的電壓范圍在上述vlt_val_scopes中進(jìn)行了定義。我們獲取到了對(duì)應(yīng)的電壓數(shù)據(jù),然后與vlt_val_scopes每個(gè)范圍數(shù)據(jù)進(jìn)行對(duì)比,從而據(jù)此得到對(duì)應(yīng)的按鍵信息。

實(shí)際結(jié)果演示:

視頻地址: 鏈接: https://pan.baidu.com/s/1RtT8Wh3ZPbasJ-dK7x1QRg 提取碼: vkyh

完整代碼:

下載地址: https://pan.baidu.com/s/1RtT8Wh3ZPbasJ-dK7x1QRg 提取碼: vkyh

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2012-01-10 12:48:52

Java

2015-09-29 09:38:50

Java程序猜大小

2020-11-10 12:08:25

開發(fā)框架

2019-09-23 09:11:02

Python文本編輯器操作系統(tǒng)

2023-02-23 14:30:27

游戲Tcl

2022-12-27 14:39:38

2023-01-03 15:16:27

2023-02-13 08:26:28

猜數(shù)字Basic

2022-08-04 13:55:08

拼數(shù)字小游戲鴻蒙

2012-09-11 09:19:35

JavaScriptJSjQ

2020-11-12 09:44:43

鴻蒙

2022-08-25 21:41:43

ArkUI鴻蒙

2020-11-13 11:53:52

4.WiFi IoT

2018-01-22 20:35:27

微信小游戲開發(fā)

2021-01-12 06:42:50

Lua腳本語言編程語言

2021-10-04 18:49:46

Fortran 77語言猜數(shù)字

2022-06-03 16:59:13

編程語言Awk

2020-10-30 17:57:11

鴻蒙HiSpark

2022-08-22 17:28:34

ArkUI鴻蒙

2012-01-17 12:39:09

JavaSwing
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)