Dependencies: Led-libary TextLCD mbed
main.cpp
- Committer:
- ladner
- Date:
- 2016-03-13
- Revision:
- 12:7b480ec47c4c
- Parent:
- 11:caa67a0ab7bd
File content as of revision 12:7b480ec47c4c:
#include "mbed.h" #include "WS2812B.h" #include "TextLCD.h" I2C i2c(P0_5,P0_4); Serial port(P0_19,P0_18); BusOut myled(P1_8,P1_9,P1_10,P1_11,P1_0,P1_1,P1_3,P1_4,P1_6,P1_7,P1_12,P1_13); AnalogIn ldr(P0_12); AnalogIn poti(P0_11); //BusOut rgb(P0_9,P1_15,P0_21); RGBOut rgb(P0_21,P0_9,P1_15); //Old: P0_13 LedOut Feld (P1_23);//P1_23 ->14 LedOut Home (P1_20);//P1_20->13 LedOut Dice (P1_21);//P1_21->12 //-> Würfel (ersten 3 LED in Binär-4. LED für 7. Zustand), Spieler, Referenz(auch RGB am board) InterruptIn Button0(P0_1); InterruptIn Button1(P1_16); InterruptIn Button2(P0_23); InterruptIn Button3(P0_10); InterruptIn Button4(P0_15); BusIn btn(P1_16,P0_23,P0_10,P0_15,P0_1); //Dice Timer Random; Timer RandomDice; Ticker DiceAnim; void DiceRun(); void setDice(char number); void DicePrint(); void DiceCal(); //umrechning des 7.Zustands in eine Zahl zwischen 1 & 6 char dicePos = 0; char diceEn = 0; char diceTick = 0; char diceNum = 0; int16_t diceDecode [7]= {0x1,0x88,0x89,0xAA,0xAB,0x1BA,0x154}; //Game #define Feldgrose 10 #define Spieler 4 #define Steine 4 char PlayPos[Spieler*Steine]; //Zahl zwischen 0 & 47 ((0xC0 -> Spieler)>>2 / 0x03 -> Stein) char Start[Spieler*Steine]; //Enthält den Index für PlayPos (nur das 'normale' Spielfend) char Ziel[Spieler*Steine]; //Enthält den Index für PlayPos (nur das 'normale' Spielfend) char Drann; //Spieler, der drann ist char count; //Für 6er & mehrfaches Würfeln beim Ansetzen char last[Spieler]; //zuletzt benutzte Spielstein, der zuletzt benutzt wurde char moglich[Steine]; char selected; //der aktuell ausgewählte Zug char Field[Spieler*Feldgrose]; //Enthält den Index für PlayPos (nur das 'normale' Spielfend) void FieldPrint(); //Ausgabe auf Com-Port void FieldGenerate(); //Berechnung von PlayPos auf Start, Ziel, Field void FeldPrint(); //Ausgabe von Field auf den Led-Streifen (Feld) der Farben void GameCal(); Ticker MoveAnim; void MoveRun(); char MoveShow; void ColorPrint(uint32_t color); //Animations char AnimField[Spieler*Feldgrose]; char AnimStart[Spieler*Steine]; char AnimZiel[Spieler*Steine]; char AnimPos[Spieler*Steine]; char AnimDo; //Feld_Animieren,Start Animieren, Ziel Animierenw void AnimCal(); //Core Interactions void reset(); void MoveDo(); void moveNext(); void moveLast(); void DiceStart(); void DiceStop(); //Button entprellung (funktioniert nicht...) void btn0(); void btn1(); void btn2(); void btn3(); void btn4(); char btnLast; //Farben uint32_t Farben[Spieler]; //Berechnete Hellichkeiten der Speiler fertig zur Ausgabe... uint32_t Background = 0; //Hintergrund (Leerfeld) uint32_t DiseC = 0x00FF00; //Würfelfarbe void ColorPrint(uint32_t color); //vorher den Header senden (manuell...) void btn0() { if((btnLast&0x10)==(btn&0x10)) return; else { if((btn&0x10)>0) reset(); else /*DoNothing*/; } btnLast=(btnLast&(0x1F-0x10))|(btn&0x10); } void btn1() { if((btnLast&0x01)==(btn&0x01)) return; else { if((btn&0x01)>0) DiceStart(); else DiceStop(); } btnLast=(btnLast&(0x1F-0x01))|(btn&0x01); } void btn2() { if((btnLast&0x02)==(btn&0x02)) return; else { if((btn&0x02)>0) moveNext(); else /*DoNothing*/; } btnLast=(btnLast&(0x1F-0x02))|(btn&0x02); } void btn3() { if((btnLast&0x04)==(btn&0x04)) return; else { if((btn&0x04)>0) moveLast(); else /*DoNothing*/; } btnLast=(btnLast&(0x1F-0x04))|(btn&0x04); } void btn4() { if((btnLast&0x08)==(btn&0x08)) return; else { if((btn&0x08)>0) MoveDo(); else /*DoNothing*/; } btnLast=(btnLast&(0x1F-0x08))|(btn&0x08); } void reset() { MoveAnim.detach(); DiceAnim.detach(); for(char i = 0;i<Spieler*Steine;i++) PlayPos[i]=i%4; for (char i = 0; i < Spieler; i++) last[i]=0; Drann=0; diceEn=0; myled = myled&0xF0F; DicePrint(); rgb.set_RGB(0); FieldGenerate(); FieldPrint(); FeldPrint(); } void Control() { while(port.readable ()) { char message = port.getc(); switch(message) { case '1': setDice(1); break; case '2': setDice(2); break; case '3': setDice(3); break; case '4': setDice(4); break; case '5': setDice(5); break; case '6': setDice(6); break; case '7': setDice(7); break; case 'A': DiceStart(); break; case 'a': DiceStop(); break; case 'B': moveNext(); break; case 'C': moveLast(); break; case 'D': MoveDo(); break; case 'I': reset(); break; } } } int main() { Random.start(); //Random.stop(); //Random.read_us(); //Ticker: //.attach(&main,[sek]); //.attach_us(&main,[micro-sec]); //.detach(); Button0.mode(PullDown); Button1.mode(PullDown); Button2.mode(PullDown); Button3.mode(PullDown); Button4.mode(PullDown); wait(0.01); Button0.rise(&reset); Button1.rise(&btn1); Button1.fall(&btn1); Button2.rise(&btn2); Button2.fall(&btn2); Button3.rise(&btn3); Button3.fall(&btn3); Button4.rise(&btn4); Button4.fall(&btn4); //myled = 0xFFF; port.baud(76800); port.format(8,Serial::None, 1); port.attach(&Control); /* Farben[0]=0x00FF00;//Rot Farben[1]=0xFF0000;//Blau Farben[2]=0x0000FF;//Grun Farben[3]=0x00FFFF;//Gelb Background = 0; //Schwarz DiseC = 0x00FF00; //Rot */ Farben[0]=0x000800;//Rot Farben[1]=0x080000;//Blau Farben[2]=0x000008;//Grun Farben[3]=0x000808;//Gelb Background = 0; //Schwarz DiseC = 0x000800; //Rot /* Farben[0]=0xFFFFFF;//Weiß Farben[1]=0xFFFFFF;//Weiß Farben[2]=0xFFFFFF;//Weiß Farben[3]=0xFFFFFF;//Weiß Background = 0xFFFFFF;//Weiß DiseC = 0xFFFFFF; //Weiß */ __disable_irq(); for(char i = 0;i<Spieler;i++) { Feld.WriteLed(Farben[i]); for(char j = 0;j<Feldgrose-1;j++) if((j==(Feldgrose-2))&(i==(Spieler-1))) Feld.WriteLed(0xFFFFFF); else Feld.WriteLed(Background); } __enable_irq(); //reset(); while(1) ; } void DiceStart() { if(diceEn==0) { RandomDice.start(); DiceAnim.attach(&DiceRun,0.1); diceEn = 1; diceTick = 1; DicePrint(); } } void DiceStop() { if(diceEn==1) { if(RandomDice.read_us()> 200) { DiceAnim.detach(); diceEn = 2; diceTick = 0; diceNum = Random.read_us()%7; diceNum = (RandomDice.read_us()+diceNum)%7+1; RandomDice.stop(); RandomDice.reset(); if(diceNum>=7) DiceCal(); //port.printf("LDiceNum:%d\n",diceNum); DicePrint(); GameCal(); } } } void DiceCal() { if(diceNum>7) diceNum=7; if(diceNum==7) { diceEn=3; for(char i = 0;i<Steine;i++) if((PlayPos[(Drann<<2)|i]>3)&&(PlayPos[(Drann<<2)|i] < 44)) for(char j = 1;j<=6;j++) { char temp = Field[(PlayPos[(Drann<<2)|i]- Steine + Feldgrose * Drann+j) % (Feldgrose*Steine)]; if(temp>0) { temp--; //(Spieler<<2)|Stein temp = (temp&0xC)>>2;//Spieler if(temp!=Drann) if(j<diceNum) diceNum=j; } } //PlayPos[(Drann<<2)|i] im Feld suchen, weiter setzen, wenn treffer, der kleiner als diceNum ->setzen von diceNum }//DiceNum == 7 if(diceNum==7) diceNum=6; port.printf("LdiceNum:%d\n",diceNum); } void setDice(char number) { if(diceEn==4) { port.printf("LWarning: diceEn:%d -> Game over\n",diceEn); } else { if(diceEn>3) port.printf("LWarning: diceEn:%d\n",diceEn); else port.printf("LdiceEn:%d\n",diceEn); if(diceEn==1) { DiceAnim.detach(); diceTick = 0; RandomDice.stop(); RandomDice.reset(); } diceEn = 2; diceNum = number; if(diceNum>=7) DiceCal(); //port.printf("LForceDice:%d\n",diceNum); DicePrint(); GameCal(); } } void DiceRun() { if(diceTick) { diceTick=0; if(dicePos<7) dicePos++; else dicePos=0; } else diceTick=1; DicePrint(); } void DicePrint() { switch(diceEn) { case 0: //Schwarz & Drann überschreiben... myled=(myled&0xFF0); myled=(myled&0x0FF)|(0x100<<Drann); port.printf("W%c%c\n",27,27); break; case 1: //Animation char dice_help = 0xFF-(1<<dicePos); myled=(myled&0xFF0)|(5)|(diceTick<<1); //myled = (myled&0xF)|(dice_help<<4); port.printf("W%c%c\n" , 27 + diceTick+((dice_help&0x1F)<<1),27 + ((dice_help& 0xE0)>>5)); break; case 2://Case 3 = Case 2 ->Anzeigen myled=(myled&0xFF0)|(diceNum); //myled=myled|0xFF0; port.printf("W%c%c\n" , 27 +(diceDecode[diceNum-1]&0x3F),27 + ((diceDecode[diceNum-1]&0x1C0)>>6)); break; case 3: myled=(myled&0xFF0)|(diceNum)|8; //myled=myled|0xFF0; port.printf("W%c%c\n" , 27 +(diceDecode[diceNum-1]&0x3F),27 + ((diceDecode[diceNum-1]&0x1C0)>>6)); break; case 4://Spiel beendet! Animation? myled=(myled&0xFF0); port.printf("W%c%c\n",27,27); break; } } void FieldGenerate() { for(char i = 0; i<Spieler*Feldgrose;i++) Field[i]=0; //Feld zurücksetzen for (char i = 0; i < Spieler*Steine; i++) { Ziel[i]=0; Start[i]=0; } for(char i = 0; i<Spieler;i++) for(char j = 0; j<Steine;j++) { if (PlayPos[(i<<2)|j] >= Steine) { if (PlayPos[(i<<2)|j] >= (Spieler * Feldgrose + Steine)) { //if (PlayPos[(i<<2)|j] < Steine * Feldgrose+Steine*2) Ziel[(PlayPos[(i<<2)|j] - (Spieler * Feldgrose + Steine))|(i<<2)] = ((i<<2)|j) + 1; //Ziel PlayPos[(i<<2)|j] - 44 } else Field[(PlayPos[(i<<2)|j]- Steine + Feldgrose * i) % (Steine * Feldgrose)] = ((i<<2)|j) + 1; //Feld (PlayPos[(i<<2)|j]- 4 + 10 * i) % 40 } else Start[PlayPos[(i<<2)|j]|(i<<2)] = ((i<<2)|j)+1; //start PlayPos[(i<<2)|j] } } void FieldPrint() { port.printf("F"); for(char i = 0;i<Spieler*Steine;i++) { port.printf("%c",27+PlayPos[i]); } port.printf("\n"); } void FeldPrint() { __disable_irq(); for(char i = 0;i<Spieler*Feldgrose;i++) if(Field[i]>0) Feld.WriteLed(Farben[((Field[i]- 1)&0x0C)>>2]); else Feld.WriteLed(Background); //char Start[Spieler]; //char Ziel[Spieler]; char i = 0; char j = 0; while(i < Steine*Spieler) { if(Start[i]>0) Home.WriteLed(Farben[((Start[i]- 1)&0x0C)>>2]); else Home.WriteLed(Background); i++; } do { if(Ziel[j]>0) Home.WriteLed(Farben[((Ziel[j]- 1)&0x0C)>>2]); else Home.WriteLed(Background); j++; }while(j < Steine*Spieler); __enable_irq(); } void AnimCal() { for(char i = 0; i<Spieler*Feldgrose;i++) AnimField[i]=0; //Feld zurücksetzen for (char i = 0; i < Spieler*Steine; i++) { AnimZiel[i]=0; AnimStart[i]=0; } AnimDo=0;//Feld_Animieren,Start Animieren, Ziel Animieren //char AnimDo; //Feld_Animieren,Start Animieren, Ziel Animierenw for (char i = 0; i < Spieler*Steine; i++) //Hauptschleife if(i==((Drann<<2)|selected)) { if(moglich[selected]==1) { if(PlayPos[i]<Steine) //nicht Draußsen { AnimDo = AnimDo|3;//Feld&Start AnimPos[i] = Steine; //Ausfahren char temp = Field[Drann*Feldgrose]; //Ansetzfeld wird analysiert if(temp>0) { //myled = myled|temp<<8; temp--; //(Spieler<<2)|Stein AnimPos[temp] = (temp & 0x03); //rücksetzung des Feldes... } } else //Draußen { AnimDo = AnimDo|1; //Feld AnimPos[i] = PlayPos[i]+diceNum;; //Weitersetzen //PlayPos[(Drann<<2)|selected] if(AnimPos[i]<Steine+Spieler*Feldgrose) //noch nicht drinnen { //Field>0 char temp = Field[ (AnimPos[i]-Steine+Feldgrose*Drann) % (Feldgrose*Steine) ]; if(temp>0) { AnimDo = AnimDo|3;//Feld&Start //myled = myled|temp<<8; temp--; //(Spieler<<2)|Stein AnimPos[temp] = (temp & 0x03); //rücksetzung des Feldes... } } else AnimDo=AnimDo|7;//Feld&Ziel (Start auch wegen Hardware) } } else AnimPos[i] = PlayPos[i]; //Spieler-pos Kopieren, weil es nicht möglich ist... } else AnimPos[i] = PlayPos[i]; //Spieler-pos Kopieren //FieldGenerate -> Anim... for(char i = 0; i<Spieler;i++) for(char j = 0; j<Steine;j++) { if (AnimPos[(i<<2)|j] >= Steine) { if (AnimPos[(i<<2)|j] >= (Spieler * Feldgrose + Steine)) { //if (AnimPos[(i<<2)|j] < Steine * Feldgrose+Steine*2) AnimZiel[(AnimPos[(i<<2)|j] - (Spieler * Feldgrose + Steine))|(i<<2)] = ((i<<2)|j) + 1; //AnimZiel AnimPos[(i<<2)|j] - 44 } else AnimField[(AnimPos[(i<<2)|j]- Steine + Feldgrose * i) % (Steine * Feldgrose)] = ((i<<2)|j) + 1; //Feld (AnimPos[(i<<2)|j]- 4 + 10 * i) % 40 } else AnimStart[AnimPos[(i<<2)|j]|(i<<2)] = ((i<<2)|j)+1; //start AnimPos[(i<<2)|j] } } void MoveRun() //Animation (zyklisch) { if(MoveShow) MoveShow = 0; else MoveShow = 1; if(MoveShow>0) { port.printf("F"); for(char i = 0;i<Spieler*Steine;i++) { port.printf("%c",27+AnimPos[i]); } port.printf("\n"); __disable_irq(); if((AnimDo&1)>0) { for(char i = 0;i<Spieler*Feldgrose;i++) if(AnimField[i]>0) Feld.WriteLed(Farben[((AnimField[i]- 1)&0x0C)>>2]); else Feld.WriteLed(Background); } //char Start[Spieler]; //char Ziel[Spieler]; char i = 0; char j = 0; if((AnimDo&2)>0) { while(i < Steine*Spieler) { if(AnimStart[i]>0) Home.WriteLed(Farben[((AnimStart[i]- 1)&0x0C)>>2]); else Home.WriteLed(Background); i++; } } if((AnimDo&4)>0) { do { if(AnimZiel[j]>0) Home.WriteLed(Farben[((AnimZiel[j]- 1)&0x0C)>>2]); else Home.WriteLed(Background); j++; }while(j < Steine*Spieler); } __enable_irq(); } else { FieldPrint(); __disable_irq(); if((AnimDo&1)>0) { for(char i = 0;i<Spieler*Feldgrose;i++) if(Field[i]>0) Feld.WriteLed(Farben[((Field[i]- 1)&0x0C)>>2]); else Feld.WriteLed(Background); } //char Start[Spieler]; //char Ziel[Spieler]; char i = 0; char j = 0; if((AnimDo&2)>0) { while(i < Steine*Spieler) { if(Start[i]>0) Home.WriteLed(Farben[((Start[i]- 1)&0x0C)>>2]); else Home.WriteLed(Background); i++; } } if((AnimDo&4)>0) { do { if(Ziel[j]>0) Home.WriteLed(Farben[((Ziel[j]- 1)&0x0C)>>2]); else Home.WriteLed(Background); j++; }while(j < Steine*Spieler); } __enable_irq(); } } void moveNext() { selected = (selected+1)%Steine; for(char i = 0;i<Steine;i++) if(moglich[selected]>0) break; else selected = (selected+1)%Steine; AnimCal(); } void moveLast() { selected = (selected+3)%Steine; for(char i = 0;i<Steine;i++) if(moglich[selected]>0) break; else selected = (selected+3)%Steine; AnimCal(); } void GameCal() { char drausen = 0; //Ziel char feld = 0; char drinnen = 0; //start char moglichAny = 1; for(char i = 0;i<Steine;i++) { if(PlayPos[(Drann<<2)|i]>=Steine) { if(PlayPos[(Drann<<2)|i] >= (Steine+Spieler*Feldgrose)) drausen++; else feld++; } else drinnen++; moglich[i]=0; } //Berechnung //Ausfahren: //drinnen >0 (Noch Spieler drinnen?) //Startfeld ist von Spieler belegt //Ziel ist frei if((drinnen>0)&&(moglichAny)) { //port.printf("LDrinnen\n"); if(((((Field[Feldgrose*Drann]-1) &0x0C) >>2)==Drann)&&(Field[Feldgrose*Drann]>0)) { //port.printf("LAusfahrt Belegt\n"); if(((((Field[(Feldgrose*Drann+diceNum)%(Feldgrose*Spieler)]-1) &0x0C) >>2)!=Drann)||(Field[(Feldgrose*Drann+diceNum)%(Feldgrose*Spieler)]==0)) { //port.printf("LZiel frei (Done)\n"); moglich[(Field[Feldgrose*Drann]-1) &0x03] = 1; moglichAny=0; } } } //Ansetzen // 6 gewürfelt //drinnen>0 //Start-feld ist nicht von Spieler belegt if((drinnen>0)&&(moglichAny)&&(diceNum==6)) { //port.printf("LDrinnen & 6 \n"); if(((((Field[Feldgrose*Drann]-1) &0x0C) >>2)!=Drann)||(Field[Feldgrose*Drann]==0)) { //port.printf("LAusfahrt frei (Done...Schleife)\n"); moglichAny=0; for(char i = 0;i<Steine;i++) if(PlayPos[(Drann<<2)|i]<Steine) moglich[i]=1; } } //Fahren if(moglichAny) { //port.printf("LNormal...\n"); for(char i = 0;i<Steine;i++) { if(PlayPos[(Drann<<2)|i]>=Spieler) //Drausen { if((PlayPos[(Drann<<2)|i]+diceNum) < (Steine+Feldgrose*Spieler))//Zeil noch am Feld { char temp = Field[(PlayPos[(Drann<<2)|i]- Steine + Feldgrose * Drann+diceNum) % (Feldgrose*Steine)]; //zielfeld if(temp>0) { //myled = myled|temp<<8; temp--; //(Spieler<<2)|Stein temp = (temp&0xC)>>2;//Spieler if(temp!=Drann) //zielfeld ist nicht ich moglich[i]=1; } else//Feld ist leer moglich[i]=1; } else {//Kollisionsberechnung ins Ziel... if((PlayPos[(Drann<<2)|i]+diceNum)<(Steine*2+ Feldgrose*Spieler))//Schiest nicht über das Ziel hinaus... if(Ziel[(PlayPos[(Drann<<2)|i]-(Steine+Feldgrose*Spieler)+diceNum)|(Drann<<2)]==0)//Zielfeld ist leer (enthält ja nur mich) moglich[i]=1; } } } } //Anzeigen der Möglichkeiten & überhaupt möglich? moglichAny=0; myled = myled&0xF0F; for(char i = 0;i<Steine;i++) { myled = myled|(moglich[i]<<i+4); moglichAny = moglichAny | moglich[i]; } if(moglichAny) //Fahren möglich { selected = (last[Drann]+Steine-1)%Steine; moveNext(); MoveAnim.attach(&MoveRun,0.3); } else //Fahren nicht möglich { if(feld<=0) //keine am Feld { if(count<2) { diceEn=0; count++; port.printf("LCount: %d\n",count); } } else //Fahren nicht möglich,spieler am Feld & 6 gewürfelt { if(diceNum==6) diceEn=0; } } } void MoveDo() { if((diceEn>1)&(diceEn<4)) { if(moglich[selected]==1) { if(PlayPos[(Drann<<2)|selected]<Steine) //nicht Draußsen { PlayPos[(Drann<<2)|selected] = Steine; //Ausfahren char temp = Field[Drann*Feldgrose]; //Ansetzfeld wird analysiert if(temp>0) { //myled = myled|temp<<8; temp--; //(Spieler<<2)|Stein PlayPos[temp] = (temp & 0x03); //rücksetzung des Feldes... } } else //Draußen { PlayPos[(Drann<<2)|selected] += diceNum; //Weitersetzen //PlayPos[(Drann<<2)|selected] if(PlayPos[(Drann<<2)|selected]<Steine+Spieler*Feldgrose) //noch nicht drinnen { //Field>0 char temp = Field[ ( PlayPos[(Drann<<2)|selected] - Steine + (Feldgrose * Drann) ) % (Feldgrose*Steine) ]; if(temp>0) { //myled = myled|temp<<8; temp--; //(Spieler<<2)|Stein PlayPos[temp] = (temp & 0x03); //rücksetzung des Feldes... } } } //else //nicht möglich } MoveAnim.detach(); last[Drann]=selected; myled = myled&0xF0F; count = 0; FieldGenerate(); //Check for Win! char temp = 0; char j = 0; char running = 1; do { temp = 0; for (char i = 0; i < Steine; i++) if (Ziel[(Drann<<2)|i]>0) temp++; if((temp==4)&(diceEn>1)) port.printf("LSpieler %d hat das Spiel beendet!\n",Drann); if(temp==4) Drann = (Drann+1)%Spieler; else { if(j==0) { if(diceNum<6) Drann = (Drann+1)%Spieler; else running = 0; } else running = 0; } diceEn = 0; j++; }while((j<=Spieler)&(running>0)); if(running==1) { port.printf("LSpiel beendet!\n"); diceEn = 4; } DicePrint(); FieldPrint(); FeldPrint(); port.printf("LDrann:%d\n",Drann); } } void ColorPrint(uint32_t color) { port.printf("%c%c%c%c\n",27+((color&0xFC0000)>>18),27+((color&0x03f000)>>12),27+((color&0x000FC0)>>6),27+(color&0x00003F)); } //http://www.repairfaq.org/REPAIR/F_SNES.html