Dependencies:   TextLCD mbed

Fork of Mbed-Mensch-1 by Projekte_werkstatt

main.cpp

Committer:
ladner
Date:
2016-02-05
Revision:
3:814d47b6991c
Parent:
2:3a90b20958ff
Child:
4:2acb70f9cd22

File content as of revision 3:814d47b6991c:

#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);

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);

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; 
    myled = myled&0xF0F;
    DicePrint();
    rgb.set_RGB(0);
    FieldGenerate();
    FieldPrint();
    FeldPrint();
}

void btn2()
{
    Drann = 0;
    PlayPos[1]=Steine+Feldgrose*Spieler;
    PlayPos[2]=5; 
    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;
    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 ())
    {
        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.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 DiceStart()
{
    if(diceEn==0)
    {
    Dice.start();
    DiceAnim.attach(&DiceRun,0.1);
    diceEn = 1;
    diceTick = 1;
    DicePrint();
    }
}
void DiceStop()
{
    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 DicePrint()
{
    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 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();
}

/*
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()
{
    if(MoveShow)
        MoveShow=0;
    else
        MoveShow = 1;
    if(MoveShow>0)
    {
        __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 = 1;
    for(char i = 0;i<Steine;i++)
    {
        if(PlayPos[(Drann<<2)|i]>3)
        {
            if(PlayPos[(Drann<<2)|i] > 43)
                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 + Feldgrose * Drann+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;
                }
            }
        }
    }
        
    moglichAny=0;
    myled = myled&0xF0F;
    for(char i = 0;i<Steine;i++)
    {
        myled = myled|(moglich[i]<<i+4);
        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++;
        }
    }
}

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
        {
            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();
    }
}