- LiTime Speicher und Akkus         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: TicTacToe/Reaktivlicht - Led als Sensor

  1. #1
    Benutzer Stammmitglied Avatar von KR-500
    Registriert seit
    26.12.2007
    Alter
    29
    Beiträge
    91

    TicTacToe/Reaktivlicht - Led als Sensor

    Anzeige

    Powerstation Test
    Hallo libes Forum,

    ich wollte euch hier jetzt mal mein neustes fertiges Projekt vorstellen. Es ist ein TicTacToe geworden, das man bedienen kann, in dem man auf die LEDs "zeigt". Das beruht auf dem Prinzip eines Reaktivlichtes, dass mit einer LED funktioniert. http://reaktivlicht.de/kochbuch.pdf
    Bild hier  
    (Quelle:http://blog.makezine.com/archive/200...ch_sensor.html)
    Ich brauche also keine Phototransistoren oder LDRs. Als Computer-Gegner hab ich mir den NegaMax-Akgorithmus ausgesucht, den hab ich allerdings abgetippt und auf meine Bedürfnisse angepasst. Der Algorithmus geht systematisch alle Eventualitäten durch und sucht die Beste aus, deswegen kann man gegen ihn nicht gewinnen, das Beste was man schaffen kann ist Unentschieden.
    Nach dem Einschalten kann man wählen ob man gegen den Computer oder einen anderen Menschen spielen will. Am besten schaut ihr euch das Video an.
    http://www.youtube.com/watch?v=UcPQEy6P6zc
    Ich benutze übrigens einen Atmega32 und Duo-LEDs von Pollin. Der Atmega ist in C programmiert. Ich freue mich auf eure Kritik, Anregungen und Verbesserungsvorschläge.
    Bei Intresse kann ich euch weitere Links zum Thema "Led als Sensor" geben.

    KR-500
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken img_2.jpg   img_1.jpg  

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von asurofreak.
    Registriert seit
    29.06.2009
    Ort
    Landkreis Vechta
    Alter
    27
    Beiträge
    332
    hi KR-500!

    das schaut ma cool aus!
    das wirkt wie son touchscreen, echt klever
    das signal der led muss man dann aber verstärken, oder?, denn ich hab mir mal so ne schaltung gebaut, wenn man eine led unter ner lichtquelle hielt, fing die andere an zu leuchten, ich brauchte dafür 2 transistoren.

    MfG
    wieder hier

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.11.2008
    Ort
    Kapfenberg
    Beiträge
    628
    Hallo!

    LED's als Sensoren zu nutzen, habe ich auch schon öfters gemacht. Ich habe mal eine Uhr gebaut, bei der die Status-LED neben der Funktion als Statusanzeige die Helligkeit misst und dementsprechend die Displayhelligkeit anpasst.

    Momentan arbeite ich an einem TicTacToe auf einem Grafik-LCD. allerdings noch ohne KI.

    Aber auf die Idee, TicTacToe und Reaktivlicht zu kombinieren, bin ich noch nicht gekommen. Hut ab, es ist wirklich ein tolles Projekt von dir geworden...

    Grüße
    Thomas

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.11.2008
    Ort
    Kapfenberg
    Beiträge
    628
    Zitat Zitat von asurofreak.
    hi KR-500!

    das schaut ma cool aus!
    das wirkt wie son touchscreen, echt klever
    das signal der led muss man dann aber verstärken, oder?, denn ich hab mir mal so ne schaltung gebaut, wenn man eine led unter ner lichtquelle hielt, fing die andere an zu leuchten, ich brauchte dafür 2 transistoren.
    Es ist nicht notwendig, da irgendwas zu verstärken. Es wird lediglich für einige ms die Led "geladen" (wie ein Kondensator) und dann geprüft, wie schnell sie sich wieder entlädt.

    Grüße
    Thomas

  5. #5
    Erfahrener Benutzer Roboter-Spezialist Avatar von asurofreak.
    Registriert seit
    29.06.2009
    Ort
    Landkreis Vechta
    Alter
    27
    Beiträge
    332
    was man mit LED´s alles so machen kann...das sowas geht wusste ich nun noch net, les mir gerade die pdf-datei durch

    MfG
    wieder hier

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von Virus
    Registriert seit
    15.09.2009
    Ort
    Duisburg
    Alter
    29
    Beiträge
    527
    feine sache, ich hatte auch an ein tictactoe auf meinem roboter gedacht, hatte aber tasten im blickfeld. duoleds wollte ich auch nutzen, hab das projekt aber bis jetzt nur hardware mäßig geplant, weil ich mir noch zuviele gedanken über den code gemacht habe, ich habbe selber und an einem wochenende mal tictactoe entschlüsselt, kann jetzt nicht mehr gegen freunde verliehren, wenn ich anfange verliehren die immer, jetzt will keiner gegen mich spielen

    kannst du deinen code mal als hilfestellung zur übersetztung von meiner strategie in ein C-programm posten?

    ist eigendlich perfekt, der RP6 hat ja auch den Atmega32
    Mit hochohmigen Grüßen
    Virus

    Es lebe der Digitalkäse !

  7. #7
    Benutzer Stammmitglied Avatar von KR-500
    Registriert seit
    26.12.2007
    Alter
    29
    Beiträge
    91
    Hallo zusammen,

    danke für die netten Kommentare. Die AI ist ja wie schon erwähnt ein NegaMax-Algorithmus. Da der Code ca. 1000 Zeilen umfasst kann ich ihn nicht ganz posten aber ich hab die wichtigsten Stellen gepostet. Wenn du oder jemand anderes Intresse am gesamten Code hat schicke ich ihm gerne eine PM. Es tut mir leid wenn der Code an einigen Stellen unleserlich ist, ich sollte ihn bei Gelegenheit noch mal überarbeiten, weil ich relativ unsauber programmiert habe. Der Algorithmus ist ja wie schon gesagt abgetippt. Der NegaMax-Algorithmus ist nur einer von vielen, den man verwenden kann, wikipedia liefert eine ganz gute Übersicht, du musst unten in den links gucken, d stehen halt noch die anderen:
    http://de.wikipedia.org/wiki/Minimax-Algorithmus
    Hier sind noch ein paar links die mir geholfen haben den Algorithmus zu verstehen:
    http://www.aihorizon.com/essays/basi...es/minimax.htm
    http://en.literateprograms.org/Tic_T...C_Plus_Plus%29
    http://www.experts-exchange.com/Prog..._21994259.html
    http://www.gm.fh-koeln.de/~hk/lehre/...sell_FINAL.pdf
    http://www.osix.net/modules/article/?id=801
    http://www.chessandpoker.com/tic_tac_toe_strategy.html
    http://www.angelfire.com/wi/wickmann/cs002.html
    Die sind zwar alle bis auf einen auf Englisch aber du wirst damit gut klargekommen. Allerdings beschäftigt sich nur der letzte Link explizit mit dem "NegaMax-Algorithmus", von dem hab ich auch abgetippt. Hier ist mein Code:
    Code:
    #include <avr/io.h>
    #include "USART_Util.h"
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <stdlib.h>
    unsigned char Board[3][3]={{2,2,2},
                               {2,2,2},
                               {2,2,2}};
    int ply=0;
    int toggle=1,win=0;
    unsigned char a[9] = {0,0,0,0,0,0,0,0,0};
    unsigned char led[9] = {0,0,0,0,0,0,0,0,0};
    unsigned int c_flag,npc=2;
    volatile unsigned char k=100;
    unsigned char OtherPlayer(unsigned char inPlayer)
    {
      if(inPlayer==1)return 0;
      return 1;
    }
    
    char doWin(unsigned char inBoard[3][3],unsigned char inPlayer)
    {
    
      if((inBoard[0][0]==inPlayer)&(inBoard[0][1]==inPlayer)&(inBoard[0][2]==inPlayer))
        {
          return 1;
        }
      if((inBoard[0][0]==inPlayer)&(inBoard[1][0]==inPlayer)&(inBoard[2][0]==inPlayer))
        {
          return 1;
        }
    
      if((inBoard[2][0]==inPlayer)&(inBoard[2][1]==inPlayer)&(inBoard[2][2]==inPlayer))
        {
          return 1;
        }
    
      if((inBoard[2][2]==inPlayer)&(inBoard[1][2]==inPlayer)&(inBoard[0][2]==inPlayer))
        {
          return 1;
        }
      if((inBoard[1][0]==inPlayer)&(inBoard[1][1]==inPlayer)&(inBoard[1][2]==inPlayer))
        {
          return 1;
        }
      if((inBoard[0][1]==inPlayer)&(inBoard[1][1]==inPlayer)&(inBoard[2][1]==inPlayer))
        {
          return 1;
        }
    
      if((inBoard[0][0]==inPlayer)&(inBoard[1][1]==inPlayer)&(inBoard[2][2]==inPlayer))
        {
          return 1;
        }
    
      if((inBoard[0][2]==inPlayer)&(inBoard[1][1]==inPlayer)&(inBoard[2][0]==inPlayer))
        {
          return 1;
        }
      return 0;
    }
    int NegaMax(unsigned char inBoard[3][3], unsigned char inPlayer)
    {
    
      if(doWin(inBoard,inPlayer)==1)
        {
          return 1;
        }
      if(doWin(inBoard,OtherPlayer(inPlayer))==1)
        {
          return -1;
        }
      int best=-2;
      int i;
      for(i=0;i<3;i++)
        {
          int j;
          for(j=0;j<3;j++)
    	{
     	 if(inBoard[i][j]==2)
    	    {
    	        inBoard[i][j]=inPlayer;
    	        int value=-NegaMax(inBoard,OtherPlayer(inPlayer));
    	        inBoard[i][j]=2;
    	        if(value>best)
    	    	{
    	    	  best=value;
    	    	}
    	    }
    	}
        }
      if(best==-2)
        {
          return 0;
        }
    
          return best;
    
    }
    void moveComputer(unsigned char inBoard[3][3])
    {
    if(ply<4){ 
      ply++;
      int i;
      int j;
    
      int best=0;
      unsigned char besti=0;
      unsigned char bestj=0;
    	for(i=0;i<3;i++)
    	  {
    	    for(j=0;j<3;j++)
    	      {
    		if(Board[i][j]==2)
    		  {
    		    Board[i][j]=1;
    		    best=-NegaMax(inBoard,0);
    		    Board[i][j]=2;
    
    		    besti=i;
    		    bestj=j;
    		    
    		  }
    	      }
    	  }  
    
      for(i=0;i<3;i++)
        {
          for(j=0;j<3;j++)
    	{
    	  if(inBoard[i][j]==2)
    	    {
    	      inBoard[i][j]=1;
    	      int score=-NegaMax(inBoard,0);
    	      if(score>best)
    		{
    		  besti=i;
    		  bestj=j;
    		  best=score;
    		}
    	      inBoard[i][j]=2;
    	    }
    	}
        }
      Board[besti][bestj]=1;
    }
    }
    
    
    
    
    
    void pc (void){
    	int q,u;
    	c_flag=1;
    	for(unsigned int e=0;e<5;e++){
    	while(c_flag){
    		if(led[0]==0){
    			PORTA |= (1<<PA0);
    			PORTB &=~ (1<<PB0);
    		}
    		if(led[1]==0){
    			PORTA |= (1<<PA1);
    			PORTB &=~ (1<<PB1);
    		}
    		if(led[2]==0){
    			PORTA |= (1<<PA2);
    			PORTB &=~ (1<<PB2);
    		}
    		if(led[3]==0){
    			PORTA |= (1<<PA3);
    			PORTB &=~ (1<<PB3);
    		}
    		if(led[4]==0){
    			PORTA |= (1<<PA4);
    			PORTB &=~ (1<<PB4);
    		}
    		if(led[5]==0){
    			PORTA |= (1<<PA5);
    			PORTB &=~ (1<<PB5);
    		}
    		if(led[6]==0){
    			PORTA |= (1<<PA6);
    			PORTB &=~ (1<<PB6);
    		}
    		if(led[7]==0){
    			PORTA |= (1<<PA7);
    			PORTB &=~ (1<<PB7);
    		}
    		if(led[8]==0){
    			PORTC |= (1<<PC7);
    			PORTD &=~ (1<<PD5);
    		}
    		_delay_us(10);
    		if(led[0]==0){
    			DDRA &=~ (1<<PA0);		
    			PORTA &=~ (1<<PA0);	
    		}
    		if(led[1]==0){
    			DDRA &=~ (1<<PA1);		
    			PORTA &=~ (1<<PA1);
    		}
    		if(led[2]==0){
    			DDRA &=~ (1<<PA2);		
    			PORTA &=~ (1<<PA2);
    		}
    		if(led[3]==0){
    			DDRA &=~ (1<<PA3);		
    			PORTA &=~ (1<<PA3);
    		}
    		if(led[4]==0){
    			DDRA &=~ (1<<PA4);		
    			PORTA &=~ (1<<PA4);
    		}
    		if(led[5]==0){
    			DDRA &=~ (1<<PA5);		
    			PORTA &=~ (1<<PA5);
    		}
    		if(led[6]==0){
    			DDRA &=~ (1<<PA6);		
    			PORTA &=~ (1<<PA6);
    		}
    		if(led[7]==0){
    			DDRA &=~ (1<<PA7);		
    			PORTA &=~ (1<<PA7);
    		}
    		if(led[8]==0){
    			DDRC &=~ (1<<PC7);		
    			PORTC &=~ (1<<PC7);
    		}
    			_delay_ms(k-75);
    			a[2] = (PINA & (1<<PINA2));
    			a[3] = (PINA & (1<<PINA3));
    			a[5] = (PINA & (1<<PINA5));
    			_delay_ms(10);
    			a[4] = (PINA & (1<<PINA4));
    			_delay_ms(65);
    			a[0] = (PINA & (1<<PINA0));		
    			a[1] = (PINA & (1<<PINA1));		
    			a[6] = (PINA & (1<<PINA6));
    			a[7] = (PINA & (1<<PINA7));
    			a[8] = (PINC & (1<<PINC7));
    		
    		DDRA = 0xFF;
    		DDRC = 0xFF;
    		if((a[0]!=0)&&(led[0]==0)){
    			PORTB |= (1<<PB0); 
    			c_flag = 0;
    			c[0]=0;
    			Board[0][0]=0;
    			led[0]=1;
    			_delay_ms(120);
    		}
    		if(a[1]!=0){
    			PORTB |= (1<<PB1);
    			c_flag = 0;
    			c[1]=0;
    			Board[0][1]=0;
    			led[1]=1;
    			_delay_ms(120);
    		}
    		if(a[2]!=0){
    			PORTB |= (1<<PB2);
    			c_flag = 0;
    			c[2]=0;
    			Board[0][2]=0;
    			led[2]=1;
    			_delay_ms(120);
    		}
    		if(a[3]!=0){
    			PORTB |= (1<<PB3);
    			c_flag = 0;
    			c[3]=0;
    			Board[1][0]=0;
    			led[3]=1;
    			_delay_ms(120);
    		}
    		if(a[4]!=0){
    			PORTB |= (1<<PB4);
    			c_flag = 0;
    			c[4]=0;
    			Board[1][1]=0;
    			led[4]=1;
    			_delay_ms(120);
    		}
    		if(a[5]!=0){
    			PORTB |= (1<<PB5);
    			c_flag = 0;
    			c[5]=0;
    			Board[1][2]=0;
    			led[5]=1;
    			_delay_ms(120);
    		}
    		if(a[6]!=0){
    			PORTB |= (1<<PB6);
    			c_flag = 0;
    			c[6]=0;
    			Board[2][0]=0;
    			led[6]=1;
    			_delay_ms(120);
    		}
    		if(a[7]!=0){
    			PORTB |= (1<<PB7);
    			c_flag = 0;
    			c[7]=0;
    			Board[2][1]=0;
    			led[7]=1;
    			_delay_ms(120);
    		}	
    		if(a[8]!=0){
    			PORTD |= (1<<PD5);
    			c_flag = 0;
    			c[8]=0;
    			Board[2][2]=0;
    			led[8]=1;
    			_delay_ms(120);
    		}
    	}
    	c_flag=1;
    	moveComputer(Board);
    	led_2();
    	if_win();
    	if(win==1){
    		for(q=0;q<3;q++){
    			for(u=0;u<3;u++){
    			Board[q][u]=2;
    			}
    		}
    		ply = 0;
    		win=0;	
    		break;
    	}
    	}
    }
    Die wichtigsten Funktionen sind OtherPLayer, doWin, NegaMax, moveComputer und pc. USART_Util.h ist eine selbst geschriebene Binliothek, die die wichtigsten USART-Funktionen beinhaltet.

    KR-500

  8. #8
    Erfahrener Benutzer Roboter Experte Avatar von Virus
    Registriert seit
    15.09.2009
    Ort
    Duisburg
    Alter
    29
    Beiträge
    527
    mein rp6 wird nur gegen menschen (nicht mensch, mensch) spielen.
    interesse an der PN oder email an timok95@gmail.com hätte ich aber trotzdem.
    Mit hochohmigen Grüßen
    Virus

    Es lebe der Digitalkäse !

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    27.11.2007
    Beiträge
    61
    hmm. Wie hast du 9 Duo-LEDs an einem AVR angeschlossen?
    Das würde mich mal interessieren. Schieberegister sehe ich auf dem Bild nicht.

  10. #10
    Erfahrener Benutzer Roboter Experte Avatar von Virus
    Registriert seit
    15.09.2009
    Ort
    Duisburg
    Alter
    29
    Beiträge
    527
    es gibt duo led, die eigendlich aus zwei leds bestehen, die in einem gehäuse vereint sind, und die mit ihren kathoden verbunden sind.
    dann kann man sie einfach wie ein 6x3 ledfeld multiplexen.
    Mit hochohmigen Grüßen
    Virus

    Es lebe der Digitalkäse !

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus