Dependencies: Led-libary TextLCD mbed
main.cpp
- Committer:
- ladner
- Date:
- 2016-03-12
- Revision:
- 8:8feae8c8ec8a
- Parent:
- 7:6b4048a2b9ff
- Child:
- 9:cb931ad9731d
File content as of revision 8:8feae8c8ec8a:
#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); //BusIn btn(P1_16,P0_23,P0_10,P0_15); 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, Start, Ziel, Referenz(auch RGB am board) // übrige 8 LED für zeit-Anzeige des Zuges einer KI InterruptIn Button0(P0_1); InterruptIn Button1(P1_16); InterruptIn Button2(P0_23); InterruptIn Button3(P0_10); InterruptIn Button4(P0_15); Timer Random; Timer RandomDice; Ticker DiceAnim; void DiceStart(); void DiceStop(); void DiceRun(); void setDice(char number); void DicePrint(); char dicePos = 0; char diceEn = 0; char diceTick = 0; char diceNum = 0; int16_t diceDecode [7]= {0x1,0x88,0x89,0xAA,0xAB,0x1BA,0x154}; #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) uint32_t Farben[Spieler]; //Berechnete Hellichkeiten der Speiler fertig zur Ausgabe... uint32_t Background = 0; //Hintergrund (Leerfeld) uint32_t DiseC = 0x00FF00; //Würfelfarbe 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(); void moveNext(); void moveLast(); Ticker MoveAnim; void MoveRun(); char MoveShow; void MoveDo(); void ColorPrint(uint32_t color); 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(); 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 btn2() { reset(); for(char i = 0;i<Spieler;i++) PlayPos[i*Spieler]=Steine+Spieler*Feldgrose; FieldGenerate(); FieldPrint(); FeldPrint(); /* for(char i = 0; i<Spieler;i++) for(char j = 0; j<Steine;j++) Start[(i<<2)|j] = ((i<<2)|j)+1; for(char i = 0; i<Spieler;i++) for(char j = 0; j<Steine;j++) Ziel[(i<<2)|j] = ((i<<2)|j)+1; FeldPrint(); */ /* Drann = 0; PlayPos[1]=Steine+Feldgrose*Spieler; //PlayPos[2]=Steine+Feldgrose*Spieler+1; PlayPos[3]=Steine+Feldgrose*Spieler+2; PlayPos[0]=Steine+Feldgrose*Spieler-1; FieldGenerate(); FieldPrint(); FeldPrint(); */ } void btn3() { /* diceNum=2; diceEn=2; Drann = 1; PlayPos[(1<<2)+0]=5; PlayPos[(1<<2)+1]=7; PlayPos[(1<<2)+2]=10; PlayPos[(1<<2)+3]=12; DicePrint(); FieldGenerate(); FieldPrint(); FeldPrint(); GameCal(); */ port.printf("W%c%c\n",27+0x3E,27+0x7); for(char i=0;i<Spieler;i++) { port.printf("w"); ColorPrint(Farben[i]); wait(1); } } void btn4() { /* for(char i = 0;i<Spieler;i++) PlayPos[i<<2]=4; FieldGenerate(); FieldPrint(); */ myled = 0; rgb.set(0,0,0); port.printf("LBtn 4 Pressed\n"); } void btn4_() { port.printf("LBtn 4 Released\n"); } 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(); wait(0.01); Button0.rise(&reset); Button1.rise(&DiceStart); Button1.fall(&DiceStop); Button2.rise(&btn2); Button3.rise(&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) { diceEn=3; for(char i = 0;i<Steine;i++) if((PlayPos[(Drann<<2)|i]>Steine -1)&&(PlayPos[(Drann<<2)|i] < Steine + Feldgrose*Spieler)) 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); DicePrint(); GameCal(); } } } void setDice(char number) { if(diceEn==1) { DiceAnim.detach(); diceTick = 0; RandomDice.stop(); RandomDice.reset(); } diceEn = 2; diceNum = number; 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("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); 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-1) //Drausen { if((PlayPos[(Drann<<2)|i]-Steine+diceNum) < 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]==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); } } } } 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 { 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 { running = 0; if(diceNum<6) Drann = (Drann+1)%Spieler; } diceEn = 0; j++; }while((j<4)&(running>0)); if(running==1) { port.printf("LSpiel beendet!\n"); diceEn = 4; } DicePrint(); FieldPrint(); FeldPrint(); } } 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)); }