作品介绍

《扑克大师》是一款可玩性高、趣味性强的1V1棋牌游戏。游戏引入“送牌”、“抽牌”、“改牌”等全新扑克玩法,并保留了“顺子”、“飞机”、“炸弹”等经典牌型组合,玩法新颖,易于上手。项目综合利用了八位数码管显示、流水灯、三按键、按键消抖、振动传感器、导航按键、红外通信等原理,按键与导航键功能设计符合玩家操作习惯。 本游戏由两名玩家参与,牌面包括1-9共9种。游戏开始时,每位玩家拿到随机20张牌,同一牌面的牌不超过四张。系统随机决定先手玩家。数码管与LED通过闪烁的方式实时显示当前牌面与页数,并标识当前有无出牌权。玩家按操作手册进行操作,先打出手中所有牌的玩家获胜,游戏结束,玩家将看到胜利/失败表情,并被告知当前所有牌的牌面之和。

游戏规则说明

  • 本游戏由两名玩家参与。

  • 牌面包括:1,2,3,4,5,6,7,8,9共9种。

  • 游戏开始时,每位玩家拿到随机20张牌,同一牌面的牌不超过四张。

  • 系统随机决定先手。玩家每次可以选择执行a~f中的任一操作,之后由对方执行操作。

  • 先打出手中所有牌的玩家获胜。游戏结束后,玩家将看到胜利/失败表情,并被告知当前所有牌的牌面之和。

  • 每一页显示8张牌,LED灯(L7~L0)代表页数及当前所在页面。

  • 特殊牌型说明:

    顺子:5张以上连续牌组成顺子。
    飞机:拥有连续2类牌,且每种牌3张。
    炸弹:拥有某一类牌4张。

  • 操作说明:

    使用顺子:将光标移动至顺子中牌面最小的牌所在位置,按下K3键,系统自动选择使用最长的顺子。顺子消失,对手得到顺子中随机一张牌。
    使用飞机:将光标移动至飞机位置,按下K2使用飞机。飞机起飞并消失,玩家可以指定自己的2张牌给对手。
    使用炸弹:将光标移动至炸弹位置,按下K1使用炸弹。炸弹引爆,玩家可以指定自己的2张牌消失。
    送牌:拨动“上”导航键,对手得到当前所选的牌。
    取牌:拨动“下”导航键,玩家得到牌库中的任一一张牌。
    改牌:按下导航键,当前所选的牌面增加1。若当前牌面为9,将更改为1。
    洗牌:振动学习板,系统将牌面按升序排序。需在执行a~f之前进行。
    (被动)收牌:当对手使用顺子、飞机或送牌时,玩家将得到一张牌,并放在起始位置。

作品视频演示

https://www.bilibili.com/video/BV1GP4y1f7UT

作品展示

图2.1 游戏欢迎界面

图2.2 游戏进行界面,此时下方玩家拥有发牌权

图2.3 游戏结束界面,下方玩家获

图2.4 振动洗牌后的闪烁显示状态

设计思路

项目设计主要分为两个大板块:含随机发牌、振动洗牌、“送牌”、“取牌”、“改牌”相应代码实现的单机布局以及基于485双机通信原理的1V1布局。项目设计核心主要包括:使用怎样的数据结构存储手中的牌、如何使用高效算法实现检测并使用特殊牌的功能、如何实现数码管与LED某一特定位的闪烁从而标识当前选中的牌面与页码、1V1如何进行初始化以确定初始发牌权、游戏过程中如何保证发牌权互斥并实时提醒玩家发牌权的有无。
操作手册

  • 以下操作可在游戏全程执行:

    振动学习板:启动“摇一摇理牌”,系统将牌面按升序排序。
    拨动导航键左键:切牌,选中上一张牌。若当前选中第一张牌,该操作将选择最后一张牌。
    拨动导航键右键:切牌,选中下一张牌。若当前选中最后一张牌,该操作将选择第一张牌。

  • 以下操作当且仅当拥有出牌权时可以执行,执行完毕之后出牌权将自动移交给对手:

    按下导航键:改牌,当前所选中的牌面加1。若当前牌面为9,该操作将牌面更改为1。
    拨动导航键上键:送牌,玩家打出选中的牌,对手得到该牌。
    拨动导航键下键:抽牌,玩家从牌库中抽取任意一张牌。
    按下K3:使用顺子,系统将选择从当前选中牌开始的、最长的顺子(5张以上牌面连续的牌组成顺子)。玩家打出顺子,对手得到顺子中随机一张牌。
    按下K2:使用飞机,系统将选择从当前选中牌开始的、最大的飞机(2种以上牌面连续、每种牌需3张的牌,组成飞机)。玩家打出飞机,并得到两次送牌机会,切牌之后再次按下K2确定送牌。
    按下K1:使用炸弹,系统将选择当前选中牌所对应的、最大的炸弹(4张以上牌面相同的牌组成炸弹)。玩家打出炸弹,并得到两次消牌机会,切牌之后再次按下K1确定消牌。

  • 以下操作被动执行:
    当对手使用顺子、飞机或执行送牌操作时,玩家将得到对手指定的牌,系统将该牌放在起始位置。

源代码

#include "STC15F2K60S2.H"
#include <stdlib.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define cstAdcPower 0X80     /*ADC电源开关*/
#define cstAdcFlag 0X10      /*当A/D转换完成后,cstAdcFlag要软件清零*/
#define cstAdcStart 0X08     /*当A/D转换完成后,cstAdcStart会自动清零,所以要开始下一次转换,则需要置位*/
#define cstAdcSpeed90 0X60   /*ADC转换速度 90个时钟周期转换一次*/
#define cstAdcChs17 0X07     /*选择P1.7作为A/D输入*/sbit sbtVib = P2 ^ 4;     //振动传感器
sbit sbtLedSel = P2 ^ 3;  //数码管与LED灯切换引脚
sbit sbtKey1 = P3 ^ 2;
sbit sbtKey2 = P3 ^ 3;
bit btKey3Flag;             /*key3键按下标志*/
sbit P3_5 = P3^5;                      //红外线发送引脚
sbit P3_7 = P3^7;                      //串口1发送引脚
uint i=0,j=0,flyCount=0,boomCount=0,turnFlag=1,findFlag,Temp,startFlag,endFlag,changFlag,HUIZHI;
uchar duanxuan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0-9
uchar weixuan[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
uchar HelloSeg[]={0x00,0x00,0x76,0x79,0x38,0x38,0x3f,0x00};
uchar WinSeg[]={0x00,0x23,0x1c,0x23,0x00};
uchar LoseSeg[]={0x00,0x23,0x54,0x23,0x00};
uchar PingSeg[]={0x00,0x23,0x08,0x23,0x00};
uint arrLed[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
uint currLed[] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe}; //当前LED为0,其余为1
uint uiLed = 0x00, flicker = 0x00,LEDP=0x00;
uint numCount=0,pageCount=3,currPage=0,currNum=0,ledCount=0,segCount=0;
uint count[]={0,0,0,0,0,0,0,0,0,0};
uint num[64];
uchar ucNavKeyCurrent;  //导航按键当前的状态
uchar ucNavKeyPast;     //导航按键前一个状态
uint mybuf,X,DispalyFlag;
uint begin_recive = 0,s_count=0;                      //接收开始标志
uint RIbuf[500],RICount=0;uint sum() {uint currSum=0;for(i=0; i<numCount; i++)currSum+=num[i];return currSum;
}void DelCurr() {count[num[currNum]]--;for(i=currNum; i<numCount; i++)num[i]=num[i+1];numCount--;pageCount=numCount/8+((numCount%8!=0)?1:0);     if(currNum>=numCount) currNum=numCount-1;
}void DelI() {count[num[i]]--;for(j=i; j<numCount; j++)num[j]=num[j+1];numCount--;pageCount=numCount/8+((numCount%8!=0)?1:0);
}unsigned char GetADC() {uchar ucAdcRes;ADC_CONTR = cstAdcPower | cstAdcStart | cstAdcSpeed90 | cstAdcChs17;//没有将cstAdcFlag置1,用于判断A/D是否结束_nop_();_nop_();_nop_();_nop_();while( !( ADC_CONTR & cstAdcFlag ) ); //等待直到A/D转换结束ADC_CONTR &= ~cstAdcFlag;           //cstAdcFlagE软件清0ucAdcRes = ADC_RES;                 //获取AD的值return ucAdcRes;
}void getRandOne() {for(i=numCount; i>0; i--)num[i]=num[i-1];num[0]=(uint)rand()%9+1;while(count[num[0]]==4)num[0]=(uint)rand()%9+1;count[num[0]]++;numCount++;pageCount=numCount/8+((numCount%8!=0)?1:0);
}void Delay5ms() {unsigned char i, j;i = 54;j = 199;do {while ( --j );}while ( --i );
}void Delay200ms()      //@11.0592MHz
{unsigned char i, j, k;_nop_();_nop_();i = 9;j = 104;k = 139;do{do{while (--k);} while (--j);} while (--i);
}uchar NavKeyCheck() {unsigned char key;key = GetADC();     //获取AD的值if( key != 255 )    //有按键按下时{Delay5ms();key = GetADC();if( key != 255 )            //按键消抖 仍有按键按下{key = key & 0xE0;       //获取高3位,其他位清零key = _cror_( key, 5 ); //循环右移5位 获取A/D转换高三位值,减小误差return key;}}return 0x07;        //没有按键按下时返回值0x07
}uint shunzi() {if(num[currNum]>5)return 0;if(count[num[currNum]]>0&&count[num[currNum]+1]>0&&count[num[currNum]+2]>0&&count[num[currNum]+3]>0&&count[num[currNum]+4]>0)return 1;return 0;
}uint feiji() {if(num[currNum]>8)return 0;if(count[num[currNum]]>2&&count[num[currNum]+1]>2)return 1;return 0;
}uint boom() {if(count[num[currNum]]>=4)return 1;return 0;
}void Delay(int n)  {while(n--);
}void sort() {for(i=0; i<numCount; i++) {for(j=i+1; j<numCount; j++) {if(num[i]>num[j]) {Temp=num[i];num[i]=num[j];num[j]=Temp;}}}
}void Vib() {sbtVib=1;Delay(40);if(sbtVib==0) {sort();}
}void UseShunzi() {Temp=num[currNum]+rand()%5;    REN = 0;   X=Temp;SBUF = 0xca;//发出发送标志0xca,触发串口中断进行数据发送Temp=num[currNum];DelCurr();for(Temp=Temp+1; Temp<=9; Temp++) {findFlag=0;for(i=0; i<numCount; i++) {if(num[i]==Temp){DelI();findFlag=1;break;}}if(!findFlag) break;}
}void UseFeiji() {Temp=num[currNum];for(; Temp<=9; Temp++) {if(count[Temp]<3) break;findFlag=3;for(i=0; i<numCount; i++) {if(findFlag==0) break;if(num[i]==Temp) {DelI();i--;findFlag--;}}}
}void UseBoom() {Temp=num[currNum];count[Temp]=0;DelCurr();for(i=0; i<numCount; i++)if(num[i]==Temp) {DelI();i--;}
}void AddOne() {count[num[currNum]]--;if(num[currNum]==9) {num[currNum]=1;} else {num[currNum]++;}count[num[currNum]]++;
}void KeyTest() {//三按键检测、特殊功能牌使用if(btKey3Flag&&shunzi()&&flyCount==0&&boomCount==0) {UseShunzi();turnFlag=0;changFlag=1;return;} else if(num[currNum]!=0&&sbtKey2==0&&flyCount>0) {REN = 0;    X=num[currNum];DelCurr();SBUF = 0xca;//发出发送标志0xca,触发串口中断进行数据发送flyCount--;turnFlag--;changFlag=1;Delay200ms();return;} else if(sbtKey2==0&&flyCount==0&&feiji()) {UseFeiji();turnFlag=2;changFlag=0;flyCount=2;Delay200ms();return;} else if(num[currNum]!=0&&sbtKey1==0&&boomCount>0) {DelCurr();boomCount--;turnFlag--;changFlag=1;Delay200ms();return;} else if(sbtKey1==0&&boomCount==0&&boom()) {UseBoom();turnFlag=2;changFlag=0;boomCount=2;Delay200ms();return;}
}void NavKey_Process() {ucNavKeyCurrent=NavKeyCheck();    //获取当前ADC值if(ucNavKeyCurrent!=0x07) {      /*导航按键是否被按下 不等于0x07表示有按下*/ucNavKeyPast=ucNavKeyCurrent;while(ucNavKeyCurrent!=0x07)        //等待导航按键松开ucNavKeyCurrent=NavKeyCheck();switch(ucNavKeyPast) {case 0x00 :                     //K3btKey3Flag=1;break;case 0x04:                     //左if(currNum>0) {currNum--;currPage=currNum/8;} else {currNum=numCount-1;currPage=currNum/8;}break;case 0x01 :                     //右if(currNum<numCount-1) {currNum++;currPage=currNum/8;} else {currNum=0;currPage=0;}break;case 0x05:                     //上if(num[currNum]!=0/*&&turnFlag*/&&boomCount==0&&flyCount==0) {REN = 0;  X=num[currNum];DelCurr();SBUF = 0xca;//发出发送标志0xca,触发串口中断进行数据发送//turnFlag=0;changFlag=1;Delay200ms();}break;case 0x02 :                     //下if(/*turnFlag&&*/boomCount==0&&flyCount==0) {getRandOne();//turnFlag=0;changFlag=1;}break;case 0x03 :                       //里if(/*turnFlag&&*/boomCount==0&&flyCount==0) {AddOne();//turnFlag=0;changFlag=1;}break;}}
}void Hello() {sbtLedSel = 0;for(j=0; j<400; j++)for(i=0; i<8; i++) {P0=0;P2=weixuan[i];P0=HelloSeg[i];Delay(500);}Delay(1000);
}void showWin() {Temp=sum();sbtLedSel = 0;for(i=0; i<5; i++) {P0=0;P2=weixuan[i];P0=WinSeg[i];Delay(500);}P0=0;P2=weixuan[5];P0=duanxuan[(Temp/100)%10];Delay(500);P0=0;P2=weixuan[6];P0=duanxuan[(Temp/10)%10];Delay(500);P0=0;P2=weixuan[7];P0=duanxuan[Temp%10];Delay(500);
}void showLose() {Temp=sum();sbtLedSel = 0;for(i=0; i<5; i++) {P0=0;P2=weixuan[i];P0=LoseSeg[i];Delay(500);}P0=0;P2=weixuan[5];P0=duanxuan[(Temp/100)%10];Delay(500);P0=0;P2=weixuan[6];P0=duanxuan[(Temp/10)%10];Delay(500);P0=0;P2=weixuan[7];P0=duanxuan[Temp%10];Delay(500);
}//void showPing() {//      Temp=sum();
//      sbtLedSel = 0;
//      for(i=0; i<5; i++) {//          P0=0;
//          P2=weixuan[i];
//          P0=PingSeg[i];
//          Delay(500);
//      }
//      P0=0;
//      P2=weixuan[5];
//      P0=duanxuan[(Temp/100)%10];
//      Delay(500);
//      P0=0;
//      P2=weixuan[6];
//      P0=duanxuan[(Temp/10)%10];
//      Delay(500);
//      P0=0;
//      P2=weixuan[7];
//      P0=duanxuan[Temp%10];
//      Delay(500);
//}void Display() {//数码管、LED的显示sbtLedSel = 0;for(i=0; i<8&&8*currPage+i<numCount; i++) {P0 = 0;P2 = weixuan[i];//选择数码管的位数if(i==currNum%8) {if(segCount<60) {P0 = 0;segCount++;} else if(segCount<120) {P0 = duanxuan[num[8*currPage+i]];segCount++;} else {segCount=0;}} else {P0 = duanxuan[num[8*currPage+i]];  //显示对应的数值}Delay(400);}P0=LEDP;sbtLedSel = 1;if(ledCount<60) {LEDP=uiLed&flicker|turnFlag;ledCount++;} else if(ledCount<120) {LEDP=uiLed|turnFlag;ledCount++;} else {LEDP=uiLed&flicker|turnFlag;ledCount=0;}Delay(200);uiLed=arrLed[pageCount];flicker=currLed[currPage];P0=0;
}void Init() {AUXR |= 0x40;        //定时器T1为1T模式,速度是传统8051的12倍,不分频。TMOD &= 0x0F;     //清除T1模式位TMOD |= 0x20;     //设置T1模式位,使用8位自动重装模式TL1 = 0x70;         //设置初值TH1 = 0x70;          //设置T1重装值TR1 = 1;              //T1运行控制位置1,允许T1计数AUXR |= 0x80;     //定时器T0为1T模式,的速度是传统8051的12倍,不分频。TMOD &= 0xF0;        //清除T0模式位TMOD |= 0x02;     //设置T0模式位,使用8位自动重装模式TL0 = 0x70;         //设置初值TH0 = 0x70;          //设T0重装值TF0 = 0;               //T0溢出标志位清零TR0 = 1;                //T0运行控制位置1,允许T0计数//定时器T2用于显示和按键消抖,500us定时16位自动重装AUXR |= 0x04;       //定时器T2为1T模式T2L = 0x66;            //低位重装值T2H = 0xEA;         //高位重装值AUXR |= 0x10;       //定时器2开始计时PCON &= 0x7F;        //波特率不倍速,SMOD=0SCON = 0x50;        //串口1使用工作方式1,REN=1(允许串行接收)AUXR &= 0xFE;        //串口1选择定时器T1作为波特率发生器,S1ST2=0AUXR1 = 0x40;      //串口1在P3.6接收,在P3.7发送PS = 1;                 //设置串口中断为最高优先级P0M1 = 0x00;P0M0 = 0xff;P2M1 = 0x00;P2M0 = 0xff;//P2M0 = 0x08;sbtLedSel = 0;      //选择数码管作为输出P1ASF = 0x80;       //P1.7作为模拟功能A/D使用ADC_RES = 0;        //转换结果清零ADC_CONTR = 0x8F;   //cstAdcPower = 1CLK_DIV = 0X00;     //ADRJ = 0    ADC_RES存放高八位结果ET1 = 0;          //禁止T1中断ET0 = 1;           //打开定时器T0中断ES = 1;             //打开串口1中断IE2 = 0X04;       //打开定时器2中断IT0 = 0;            //设置IT0上升沿触发IT1 = 0;EA = 1;             //CPU开放中断LEDP=0x00;btKey3Flag=0;startFlag=1;endFlag=0;turnFlag=1;DispalyFlag=1;changFlag=1;HUIZHI=0;
}void Time0() interrupt 1
{if(P3_7==0)          //P3_5根据P3_7的信号产生脉冲{P3_5 = ~P3_5;}else                     //如果P3.7=1则P3.5输出0P3_5 = 0;
}/********************************* 函数名:URAT1* 描述  :串口1中断的操作。发送完毕TI自动置1,产生中断; 接收完毕RI值1,产生中断* 输入  :无* 输出  :无
********************************/
void URAT1() interrupt 4
{if(TI)                                             //判断发送中断{   TI = 0;                                            //发送中断请求标志位清0if(s_count < 1)                 //发送个数小于显示个数{SBUF=X;   //继续发送s_count ++;}else{if(s_count == 1)         //发送个数等于显示个数{   s_count ++;SBUF = 0x55;                      //发送结束标志}else                                           //发送完毕后,已发送个数清零,打开串口接收{s_count = 0;REN = 1;                                 }}} if(RI)                                              //判断是否接收中断{RI = 0;                                         //接收中断请求标志位清0mybuf = SBUF;                             //把这次接收到的数据存入自定义的缓存中if(mybuf == 0x55)                     //判断接收结束{begin_recive = 0;                 //接收结束IE2 = 0x04;                              //打开定时2中断}if(begin_recive)                      //如果开始了{    RIbuf[RICount] = SBUF;     //接收数据RICount++;                              //显示个数+1}}if(mybuf == 0xca)                      //判断开始接收标志{begin_recive = 1;                   //接收开始IE2 = 0x00;                              //关闭定时器T2中断,停止按键检测与数码管扫描P0 = 0;                         RICount = 0;                               //显示个数清零}
}void Deal() {//发牌for(i=0; i<20; i++) {num[i]=(uint)rand()%9+1;if(count[num[i]]==3)num[i]=(uint)rand()%9+1;while(count[num[i]]==4)num[i]=(uint)rand()%9+1;count[num[i]]++;}numCount=20;pageCount=3;currPage=0;currNum=0;
}void RICheck() {if(RICount==0) return;while(RICount>0) {if(RIbuf[0]==0x55||RIbuf[0]==0xca) {}else if(!startFlag&&RIbuf[0]>=10) {//游戏结束Temp=sum()+10;REN=0; X=Temp;SBUF = 0xca;//发出发送标志0xca,触发串口中断进行数据发送//}while(1) {showLose();}} else if(RIbuf[0]>0&&RIbuf[0]<10){for(i=numCount; i>0; i--)num[i]=num[i-1];num[0]=RIbuf[0];count[RIbuf[0]]++;numCount++;pageCount=numCount/8+((numCount%8!=0)?1:0);   }for(j=0; j<RICount-1; j++)RIbuf[j]=RIbuf[j+1];RICount--;   }
}void Timer2() interrupt 12
{Vib();RICheck();
}void main() {Init();Deal();Hello();while(1) {if(turnFlag==0) turnFlag=1;startFlag=0;Vib();sbtVib=1;Display();P0 = 0;             //P0清零Vib();NavKey_Process();Vib();KeyTest();Vib();btKey3Flag=0;if(numCount==0) {REN = 0;   X=10;SBUF = 0xca;//发出发送标志0xca,触发串口中断进行数据发送         while(1) showWin();}Vib();}
}

嵌入式学习板开发:STC单片机扑克游戏设计(C语言)相关推荐

  1. 【VSCode PlatformIO】开发STC单片机头文件和常用外设驱动头文件获取方式

    [VSCode PlatformIO]开发STC单片机头文件和常用外设驱动头文件获取方式 相关篇<[VSCode PlatformIO] STC单片机开发头文件制作与添加方法> 相关篇&l ...

  2. VSCode PlatformIO开发STC单片机注意事项

    VSCode PlatformIO开发STC单片机注意事项 首先需要注意代码的语法 附上本论坛一位网友总结的笔记 其实开源的SDCC+code blocks也不错的.SDCC语法与keil C有一点点 ...

  3. 视频教程:嵌入式stm32项目开发之心率检测仪的设计与实现

    视频教程:嵌入式stm32项目开发之心率检测仪的设计与实现 本课程主要基于心率检测仪的设计与实现讲解STM32开发技术,STM32开发板广泛应用于仪器仪表.家用电器.医用设备.航空航天.专用设备的智能 ...

  4. 视频教程免费分享:嵌入式stm32项目开发之心率检测仪的设计与实现

    视频教程免费分享:嵌入式stm32项目开发之心率检测仪的设计与实现 本课程主要基于心率检测仪的设计与实现讲解STM32开发技术,STM32开发板广泛应用于仪器仪表.家用电器.医用设备.航空航天.专用设 ...

  5. 免费视频教程:嵌入式stm32项目开发之心率检测仪的设计与实现

    免费视频教程:嵌入式stm32项目开发之心率检测仪的设计与实现 本课程主要基于心率检测仪的设计与实现讲解STM32开发技术,STM32开发板广泛应用于仪器仪表.家用电器.医用设备.航空航天.专用设备的 ...

  6. HNU小学期计算机系统设计与创新基础训练——基于STC学习板的加密信息存储与游戏操作系统(第一部分设计思路+基础原理)

    HNU小学期计算机系统设计与创新基础训练--加密信息存储与游戏操作系统 一. 选题名称 二. 选题背景 三. 实现功能 1. 主要功能 2. 细节设计 四. 设计思路 五. 基本原理 1. 数码管与发 ...

  7. 【嵌入式Linux】嵌入式Linux驱动开发基础知识之驱动设计的思想:面向对象/分层/分离

    文章目录 前言 1.分离设计 驱动程序分析---程序分层 通用驱动程序---面向对象 个性化驱动程序---分离 APP 程序分析 前言 韦东山嵌入式Linux驱动开发基础知识学习笔记 文章中大多内容来 ...

  8. 五子棋游戏设计VHDL语言

    本设计实现五子棋游戏设计,使用VHDL语言 quartusII 或者 vivado均可 通过VGA显示实时的棋盘,双方可以通过按键来控制黑棋和白棋的位置,实现五子棋游戏的功能. 开始和胜利的界面如下: ...

  9. 基于单片机的数字电压表设计c语言,基于单片机的数字电压表设计(.doc

    基于单片机的数字电压表设计( 成绩 西南科技大学城市学院 City College of Southwest University Of Science and Technology 基于单片机的数字 ...

最新文章

  1. CodeGen编写自定义表达式标记
  2. JavaScript-数据引用类型对象
  3. redis mysql主从同步_手撕Redis,主从同步
  4. sap系统操作流程财务软件_金蝶财务软件的操作流程汇总
  5. C++ 中的集合与字典
  6. 【CyberSecurityLearning 75】DC系列之DC-6渗透测试(WordPress)
  7. 资源 | Deeplearning.ai课程与笔记汇总
  8. nuget 包管理器
  9. MySql笔记:Can't create table 'mydb3.#sql-f48_1' (errno: 150
  10. 在java中产生随机数_在Java中产生随机数的两个方法
  11. cdr怎么做文字路径_抖音短视频中边说过边出现文字的是怎么做的?教程如下
  12. 人工智能最前沿的技术视频,大量教程
  13. 缓存数据一致性-解决方案
  14. 扫外部二维码进入小程序,并且在小程序内获取二维码链接
  15. 扩展spring之ext-spring-cache
  16. 《刻意练习》读书笔记之一
  17. 自然语言处理--信息模型
  18. 大数据平台架构实战(二)IntelliJ IDEA搭建hadoop
  19. oschina使用pages
  20. 【电子设计大赛】2021 年全国大学生电子设计竞赛仪器设备和主要元器件及器材清单

热门文章

  1. sap 可配置物料 super BOM的相关配置
  2. 房屋销售/楼盘管理信息系统(c课设/大作业)
  3. 亚信UED前端流程自动化构建工具
  4. python调用函数指定次数_扣丁学堂Python在线视频之Python限制函数调用次数实例
  5. C++转Java学习总结
  6. [二] Numpy数据存取与函数
  7. 微星主板jsp1接线图_SPI编程器刷带JSPI1的联想主板(据说是微星OEM的)
  8. [附源码]java毕业设计高校教师教学助手系统的设计与实现
  9. apache https反向代理设置方案
  10. 小样本学习记录————相似性计算经典网络结构(孪生网络、匹配网络、原型网络、 关系网络)