Dependencies:   TextLCD mbed

Fork of Mbed-Mensch-1 by Projekte_werkstatt

Revision:
1:0eaa7682f7e1
Parent:
0:e97a6a69fe4b
Child:
2:3a90b20958ff
--- a/main.cpp	Thu Jan 21 13:10:55 2016 +0000
+++ b/main.cpp	Thu Feb 04 15:51:34 2016 +0000
@@ -1,102 +1,588 @@
 #include "mbed.h"
+#include "WS2812B.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);
-DigitalOut test (P0_13);
+//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);
+
+LedOut Feld (P0_13);
+//LedOut Other(P0_13); //-> 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);
 
-uint32_t ledbuffer[100];
-uint32_t colourbuf[100];
-char Index = 0;
-char length = 60;
-void writeled(uint32_t leddata); // Prototyp 
-void writeledbit(char wert);
-void next();
-void last();
-void output();
-int main() 
+Timer Random;
+Timer Dice;
+
+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];           //Enthält den Index für PlayPos (nur das 'normale' Spielfend)
+char Ziel[Spieler];            //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...
+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 reset()
+{
+    MoveAnim.detach();
+    DiceAnim.detach();
+    for(char i = 0;i<Spieler*Steine;i++)
+        PlayPos[i]=i%4;
+    Drann=0;
+    diceEn=0; 
+    DicePrint();
+    rgb.set_RGB(0);
+    FieldGenerate();
+    FieldPrint();
+    FeldPrint();
+}
+
+void btn2()
+{
+    diceEn=0;
+    Drann=2;
+    PlayPos[4]=14;
+    FieldGenerate();
+    FieldPrint();
+    FeldPrint();
+}
+void btn3()
 {
-    Button1.rise(&next);
-    Button2.rise(&last);
-    rgb = 7;
-    colourbuf[0]=0x0000FF;//Grün
-    colourbuf[1]=0x00FF00;//Rot
-    colourbuf[2]=0xFF0000;//Blau
-    colourbuf[3]=0x00FFFF;//Gelb
-    colourbuf[4]=0x000000;//Aus
-    output();
-    while(1) ;
-    while(1) 
+    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;
+    FieldGenerate();
+    FieldPrint();
+    FeldPrint();
+    GameCal();
+}
+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 ())
     {
-     writeled(0);
-     test=0;
-     wait(1);
+        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;
+        }
     }
 }
 
-void output()
+int main() 
 {
-    for(char i = 0;i<Index;i++)
-        writeled(0);
-    writeled(colourbuf[3]);
-    for(char i = Index;i<length-1;i++)
-        writeled(0);
+    Random.start();
+    //Random.stop();
+    //Random.read_us();
+    
+    //Ticker:
+    //.attach(&main,[sek]);
+    //.attach_us(&main,[micro-sec]);
+    //.detach();
+    
+    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]=0x001000;//Grün
+    Farben[1]=0x100000;//Rot
+    Farben[2]=0x000010;//Blau
+    Farben[3]=0x001010;//Gelb
+    //Farben[4]=0xFFFFFF;//Weiß
+    
+    __disable_irq();
+    for(char i = 0;i<Spieler;i++)
+    {
+        Feld.WriteLed(Farben[i]);
+        for(char j = 0;j<Feldgrose-1;j++)
+            Feld.WriteLed(0);
+    }
+    __enable_irq();
+    
+    
+    while(1) ;        
 }
 
-void next()
+void DiceStart()
+{
+    if(diceEn==0)
+    {
+    Dice.start();
+    DiceAnim.attach(&DiceRun,0.1);
+    diceEn = 1;
+    diceTick = 1;
+    DicePrint();
+    }
+}
+void DiceStop()
 {
-    if(Index<(length-1))
-        Index++;
-    output();
+    if(diceEn==1)
+    {
+        if(Dice.read_us()> 200)
+        {
+            DiceAnim.detach();
+            diceEn = 2;
+            diceTick = 0;
+            diceNum = Random.read_us()%7;
+            diceNum = (Dice.read_us()+diceNum)%7+1;
+            Dice.stop();
+            Dice.reset();
+            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);
+            DicePrint();
+            GameCal();
+        }
+    }
+}
+void setDice(char number)
+{
+    if(diceEn==1)
+    {
+        DiceAnim.detach();
+        diceTick = 0;
+        Dice.stop();
+        Dice.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 last()
+void DicePrint()
 {
-    if(Index>=0)
-        Index--;
-    output();
+    switch(diceEn)
+    {
+        case 0:
+        myled=(myled&0xFF0);
+        port.printf("W%c%c\n",27,27);
+        break;
+        case 1:
+        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:
+        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;
+    }
 }
-void writeled(uint32_t leddata)
-{ int i;
-       for(i=0;i<24;i++)
-       {
-       
-         writeledbit(((leddata>>i)&0x000001)==0x000001);
-       }
+
+void FieldGenerate()
+{
+    for(char i = 0; i<Spieler*Feldgrose;i++)
+        Field[i]=0; //Feld zurücksetzen
+        
+    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] > Steine * Feldgrose+Steine-1)
+                {
+                    if (PlayPos[(i<<2)|j] < Steine * Feldgrose+Steine*2)
+                        Ziel[PlayPos[(i<<2)|j] - Steine * Feldgrose+Steine] = ((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)|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(0);
+    __enable_irq();
 }
-void writeledbit(char wert)  // Funktion schreibe bit
+
+/*
+char PlayPos[Spieler*Steine];  //Zahl zwischen 0 & 47 ((0xC0 -> Spieler)>>2 / 0x03 -> Stein)
+char PlayPosOld[Spieler*Steine];
+char Start[Spieler];           //Enthält den Index für PlayPos (nur das 'normale' Spielfend)
+char Ziel[Spieler];            //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...
+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 MovePrint();                */
+
+void MoveRun()
 {
-    int j;
-    if(wert)
+    if(MoveShow)
+        MoveShow=0;
+    else
+        MoveShow = 1;
+    if(MoveShow>0)
     {
-        test=1; // data 1
-        for(j=0;j<5;j++) 
+        __disable_irq();
+        port.printf("F");
+        for(char i = 0;i<Spieler*Steine;i++)
+            {
+                if(i==((Drann<<2)|selected))
+                {
+                    if(PlayPos[i]<Steine)
+                        port.printf("%c",27+Steine);
+                        else
+                            port.printf("%c",27+PlayPos[i]+diceNum);
+                }
+                else
+                    port.printf("%c",27+PlayPos[i]);
+            }
+        port.printf("\n");
+        __enable_irq();
+    }
+    else
+        FieldPrint();
+}
+
+void moveNext()
+{
+    selected = (selected+1)%Steine;
+    for(char i = 0;i<Steine;i++)
+        if(moglich[selected]>0)
+            break;
+        else
+            selected = (selected+1)%Steine;
+}
+
+void moveLast()
+{
+    selected = (selected+3)%Steine;
+    for(char i = 0;i<Steine;i++)
+        if(moglich[selected]>0)
+            break;
+        else
+            selected = (selected+3)%Steine;
+}
+
+void GameCal()
+{
+    char drausen = 0; //Ziel
+    char feld = 0;
+    char drinnen = 0; //start
+    char moglichAny = 0;
+    for(char i = 0;i<Steine;i++)
+    {
+        if(PlayPos[(Drann<<2)|i]>3)
         {
-        __nop();    
+            if(PlayPos[(Drann<<2)|i] > 43)
+                drausen++;
+            else
+                feld++;
         }
-        test=0;
-        for(j=0;j<1;j++)
-        {
-        __nop();   
-        }
+        else
+            drinnen++;
+        moglich[i]=0;
+    }
+    //Berechnung
+    if((drinnen>0)&&((((Field[Feldgrose*Drann]-1) &0x0C) >>2)==Drann)&&(Field[Feldgrose*Drann]>0))
+    {//Ausfahren
+        moglich[(Field[Feldgrose*Drann]-1) &0x03] = 1;
     }
     else
     {
-        test=1; // data 0
-        for(j=0;j<1;j++) 
+        if((diceNum==6)&&(drinnen>0)) //Ansetzen
+        {
+            for(char i = 0;i<Steine;i++)
+                if(PlayPos[(Drann<<2)|i]<Steine)
+                    moglich[i]=1;
+        }
+        else                      //'normal'
         {
-        __nop();    
+            for(char i = 0;i<Steine;i++)
+            {
+                if(PlayPos[(Drann<<2)|i]>Spieler-1)
+                {
+                    char temp = Field[(PlayPos[(Drann<<2)|i]- Steine + Feldgrose * Drann+diceNum) % (Feldgrose*Steine)];
+                    if(temp>0)
+                    {
+                        //myled = myled|temp<<8;
+                        temp--; //(Spieler<<2)|Stein
+                        temp = (temp&0xC)>>2;//Spieler
+                        if(!(temp==Drann))
+                            moglich[i]=1;
+                    }
+                    else
+                        moglich[i]=1;
+                }
+            }
+        }
+    }
+    
+    myled = myled&0xF0F;
+    for(char i = 0;i<Steine;i++)
+        myled = myled|(moglich[i]<<i+4);
+    for(char i = 0;i<Steine;i++)
+        moglichAny = moglichAny | moglich[i];
+    if(moglichAny)
+    {
+        selected = (last[Drann]+Steine-1)%Steine;
+        moveNext();
+        MoveAnim.attach(&MoveRun,0.3);
+    }
+    else
+    {
+        if(feld)
+        diceEn = 1;
+        else
+        {
+        diceEn=0;
+        count++;
         }
-        test=0;
-        for(j=0;j<5;j++)
+    }
+}
+
+void MoveDo()
+{
+    if(diceEn>1)
+    {
+        if(PlayPos[(Drann<<2)|selected]<Steine)
+        {
+            PlayPos[(Drann<<2)|selected] = Steine;
+            char temp = Field[Drann*Feldgrose];
+            if(temp>0)
+            {
+                //myled = myled|temp<<8;
+                temp--; //(Spieler<<2)|Stein
+                PlayPos[temp] = (temp & 0x03); //rücksetzung des Feldes...
+            }
+        }
+        else
         {
-        __nop();   
+            PlayPos[(Drann<<2)|selected] += diceNum;
+            //PlayPos[(Drann<<2)|selected]
+            if((PlayPos[(Drann<<2)|selected]>=Steine)&&(PlayPos[(Drann<<2)|selected]<Steine+Spieler*Feldgrose))
+            {
+                //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...
+                }
+            }
         }
-    }           
+        MoveAnim.detach();
+        last[Drann]=selected;
+        if(diceNum<6)
+        {
+            Drann = (Drann+1)%Spieler;
+        }
+        diceEn = 0;
+        count = 0;
+        DicePrint();
+        myled = myled&0xF0F;
+        FieldGenerate();
+        FieldPrint();
+        FeldPrint();
+    }
 }
\ No newline at end of file