Absender: Frank Menzel
Datum: Do, 01.10.2009 21:13:05
Hallo, anbei mal ein Patch, um den bot Schach spielen zu lassen. Weiterhin der Chessparcour. Zur Beschreibung mal aus der Quelle rauskopiert: * Der Bot spielt Schach! Das Schachverhalten ermoeglicht die manuelle Eingabe * eines Schachzuges des Spielers 1 (weiss) ueber das Screeninterface. Nach Betaetigen * der GO-Taste zieht der Bot-Spieler und der Bot fährt auf dem Schachbrett diesen * Zug nach. Nun ist der menschliche Spieler wieder am Zug via Screeneingabe bzw. drückt sofort GO, * um fuer sich den Zug machen zu lassen. Am besten ist es (weil ja die Schachfiguren nicht visualisiert werden), * sich parallel dazu ein echtes Schachbrett aufzubauen und manuell die Zuege nachzuvollziehen. In meinem ersten Test * musste ich eine Niederlage gegen den Bot einstecken:-) * Fuer das Verhalten ist das Chess-Layout zu laden, damit wenigstens die Schachfelder visualisiert werden und damit die * Botfahrten der gegnerischen Schachzuege. Die gruenen Felder stehen hierbei stellvertretend fuer die weissen Felder. * Inspiriert zu diesem Verhalten wurde ich durch folgende Seiten: * http://bralug.de/wiki/BLIT2008-Board_spielt_Schach * Detailliertes zu dem Micro-Max Schach ist hier zu finden: * http://home.hccnet.nl/h.g.muller/max-src2.html * * Brainstorming fuer moegliche Erweiterungen: * Der Bot koennte gegen den anderen spielen ohne Mensch, d.h. Bot 1 ist Spieler 1 und der andere der Gegenspieler. * Jeder bot macht jeweils einen Zug und fährt diesen ab. Danach ist der andere dran. Dies muesste/koennte dann ueber die * bot_2_bot-Kommunikation laufen. Noch schoener waere es natuerlich, echte Spielfiguren auf dem Java3D-Schachbrett zu haben * (oder zuerst auch einfache Objekte), wobei der bot sich jeweils die Figur greift (bot_catch_pillar) und an der Zielposition * ablaedt (bot_unload_pillar)... * Da es mir endlich geglückt war, Eclipse-Galileo mit allem notwendigen Zeugs zu installieren, konnte ich endlich den Patch auf die aktuelle Quelle fertig stellen. So wünsche ich viel Spaß:-) Gruß, Frank
### Eclipse Workspace Patch 1.0
#P ct-Bot
Index: bot-logic/bot-logik.c
===================================================================
--- bot-logic/bot-logik.c (revision 1618)
+++ bot-logic/bot-logik.c (working copy)
@@ -346,6 +346,10 @@
insert_behaviour_to_list(&behaviour, new_behaviour(40, bot_follow_object_behaviour, INACTIVE));
#endif
+ #ifdef BEHAVIOUR_DRIVE_CHESS_AVAILABLE
+ insert_behaviour_to_list(&behaviour, new_behaviour(39, bot_drive_chess_behaviour, INACTIVE));
+ #endif
+
#ifdef BEHAVIOUR_DRIVE_STACK_AVAILABLE
insert_behaviour_to_list(&behaviour, new_behaviour(33, bot_drive_stack_behaviour, INACTIVE));
#endif
Index: bot-logic/behaviour_drive_chess.c
===================================================================
--- bot-logic/behaviour_drive_chess.c (revision 0)
+++ bot-logic/behaviour_drive_chess.c (revision 0)
@@ -0,0 +1,746 @@
+/*
+ * c't-Bot
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307, USA.
+ *
+ */
+
+
+/*!
+ * @file behaviour_drive_chess.c
+ * @brief Der Bot spielt Schach! Das Schachverhalten ermoeglicht die manuelle Eingabe
+ * eines Schachzuges des Spielers 1 (weiss) ueber das Screeninterface. Nach Betaetigen
+ * der GO-Taste zieht der Bot-Spieler und der Bot fährt auf dem Schachbrett diesen
+ * Zug nach. Nun ist der menschliche Spieler wieder am Zug via Screeneingabe bzw. drückt sofort GO,
+ * um fuer sich den Zug machen zu lassen. Am besten ist es (weil ja die Schachfiguren nicht visualisiert werden),
+ * sich parallel dazu ein echtes Schachbrett aufzubauen und manuell die Zuege nachzuvollziehen. In meinem ersten Test
+ * musste ich eine Niederlage gegen den Bot einstecken:-)
+ * Fuer das Verhalten ist das Chess-Layout zu laden, damit wenigstens die Schachfelder visualisiert werden und damit die
+ * Botfahrten der gegnerischen Schachzuege. Die gruenen Felder stehen hierbei stellvertretend fuer die weissen Felder.
+ * Inspiriert zu diesem Verhalten wurde ich durch folgende Seiten:
+ * http://bralug.de/wiki/BLIT2008-Board_spielt_Schach
+ * Detailliertes zu dem Micro-Max Schach ist hier zu finden:
+ * http://home.hccnet.nl/h.g.muller/max-src2.html
+ *
+ * Brainstorming fuer moegliche Erweiterungen:
+ * Der Bot koennte gegen den anderen spielen ohne Mensch, d.h. Bot 1 ist Spieler 1 und der andere der Gegenspieler.
+ * Jeder bot macht jeweils einen Zug und fährt diesen ab. Danach ist der andere dran. Dies muesste/koennte dann ueber die
+ * bot_2_bot-Kommunikation laufen. Noch schoener waere es natuerlich, echte Spielfiguren auf dem Java3D-Schachbrett zu haben
+ * (oder zuerst auch einfache Objekte), wobei der bot sich jeweils die Figur greift (bot_catch_pillar) und an der Zielposition
+ * ablaedt (bot_unload_pillar)...
+ *
+ * @author Frank Menzel (Menzelfr@xxxxxx)
+ * @date 15.09.2009
+ */
+
+
+
+
+
+
+#include "bot-logic/bot-logik.h"
+#include <stdlib.h>
+#include "log.h"
+#include "rc5-codes.h"
+#include "display.h"
+
+#ifdef BEHAVIOUR_DRIVE_CHESS_AVAILABLE
+
+
+//#define DEBUG_CHESS // Schalter fuer Debugausgaben
+
+
+#ifdef MCU
+#undef DEBUG_CHESS
+#endif
+#ifndef LOG_AVAILABLE
+#undef DEBUG_CHESS
+#endif
+#ifndef DEBUG_CHESS
+#undef LOG_DEBUG
+#define LOG_DEBUG(a, ...) {}
+#endif
+
+
+
+/***************************************************************************/
+/* Los geht es mit den benoetigten Routinen fuer das Schachprogramm */
+/* sowie dem Schachprogramm dann selbst */
+/***************************************************************************/
+
+/*! Digitstellen des Schachzuges fuer Eingabe als auch fuer Anzeige des berechneten Zuges */
+uint8_t d_0 = '0';
+uint8_t d_1 = '0';
+uint8_t d_2 = '0';
+uint8_t d_3 = '0';
+
+
+
+/*!
+ * Ausgabe einer Stelle des Zuges auf dem Display
+ * @param offset Position der anzuzeigenden Stelle
+ * @param d Ausgabezeichen
+ */
+void print_move_digit(uint8_t offset, uint8_t d) {
+
+ switch (offset) {
+ case 0:
+ d_0=d;
+ break;
+
+ case 1:
+ d_1=d;
+ break;
+
+ case 2:
+ d_2=d;
+ break;
+
+ case 3:
+ d_3=d;
+ break;
+ }
+}
+
+
+
+/*!
+ * Loeschen der Zug-Anzeigestellen auf dem Display
+ */
+void clean_move_digits(void) {
+ d_0=' ';
+ d_1=' ';
+ d_2=' ';
+ d_3=' ';
+}
+
+/*!
+ * Anzeige der 4 Zug-Zeichenstellen
+ * @param d0 Zeichen an 1. Stelle
+ * @param d1 Zeichen an 2. Stelle
+ * @param d2 Zeichen an 3. Stelle
+ * @param d3 Zeichen an 4. Stelle
+ */
+void print_move(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) {
+ // globale Vars nur setzen, werden vom Display selbst ausgegeben
+ d_0 = d0;
+ d_1 = d1;
+ d_2 = d2;
+ d_3 = d3;
+}
+
+
+
+/***************************************************************************/
+/* micro-Max, */
+/* A chess program smaller than 2KB (of non-blank source), by H.G. Muller */
+/***************************************************************************/
+/* version 4.8 (1953 characters) features: */
+/* - recursive negamax search */
+/* - all-capture MVV/LVA quiescence search */
+/* - (internal) iterative deepening */
+/* - best-move-first 'sorting' */
+/* - a hash table storing score and best move */
+/* - futility pruning */
+/* - king safety through magnetic, frozen king in middle-game */
+/* - R=2 null-move pruning */
+/* - keep hash and repetition-draw detection */
+/* - better defense against passers through gradual promotion */
+/* - extend check evasions in inner nodes */
+/* - reduction of all non-Pawn, non-capture moves except hash move (LMR) */
+/* - full FIDE rules (expt under-promotion) and move-legality checking */
+
+#define M 0x88 /* Unused bits in valid square */
+#define S 128 /* Sign bit of char */
+#define I 8000 /* Infinity score */
+#define U 18 /* D() Stack array size */
+
+struct {
+short q,l,e; /* Args: (q,l)=window, e=current eval. score */
+short m,v, /* m=value of best move so far, v=current evaluation */
+ V,P;
+unsigned char E,z,n; /* Args: E=e.p. sqr.; z=level 1 flag; n=depth */
+signed char r; /* step vector current ray */
+unsigned char j, /* j=loop over directions (rays) counter */
+ B,d, /* B=board scan start, d=iterative deepening counter */
+ h,C, /* h=new ply depth?, C=ply depth? */
+ u,p, /* u=moving piece, p=moving piece type */
+ x,y, /* x=origin square, y=target square of current move */
+ F, /* F=e.p., castling skipped square */
+ G, /* G=castling R origin (corner) square */
+ H,t, /* H=capture square, t=piece on capture square */
+ X,Y, /* X=origin, Y=target square of best move so far */
+ a; /* D() return address state */
+} _, A[U],*J=A+U; /* _=working set, A=stack array, J=stack pointer */
+
+short Q, /* pass updated eval. score */
+K, /* input move, origin square */
+i,s, /* temp. evaluation term */
+Dq,Dl,De, /* D() arguments */
+DD; /* D() return value */
+
+const signed char w[] PROGMEM = {
+ 0,2,2,7,-1,8,12,23}; /* relative piece values */
+
+const signed char o[] PROGMEM = {
+ -16,-15,-17,0,1,16,0,1,16,15,17,0,14,18,31,33,0, /* step-vector lists */
+ 7,-1,11,6,8,3,6, /* 1st dir. in o[] per piece*/
+ 6,3,5,7,4,5,3,6}; /* initial piece setup */
+
+unsigned char L, /* input move, target square*/
+b[129], /* board: half of 16x8+dummy*/
+c[5], /* input move ASCII buffer */
+k, /* moving side 8=white 16=black*/
+O, /* pass e.p. flag at game level*/
+R, /* captured non pawn material */
+DE,Dz,Dn, /* D() arguments */
+Da, /* D() state */
+W=99; /* @ temporary */
+/*hv;*/ /* zeige Hauptvariante, d.h automat. Zugermittlung oder nicht*/
+
+
+//*********************************************************
+unsigned char st=2; /* Spielstufe (Level) */
+
+#define UNIX // at least for this program, MS-Windows is UNIX, Erhoehung Zaehler in jedem Durchlauf
+
+
+long timer; // wird alle 4.096ms erhoeht bzw. durch Increment
+
+int16_t MaxMoves = 40, MaxTime = 30*40, moves;
+long nodes, newNodes;
+
+
+#define F_NEWGAME '3'
+#define F_LEVEL '.'
+#define F_FAVORIT '?'
+
+#define CL '9'
+#define GO ':'
+
+
+
+
+//#ifdef PC
+ #define o(ndx) (signed char)o[ndx]
+ #define w(ndx) (signed char)w[ndx]
+//#else
+ //#define o(ndx) (signed char)pgm_read_byte_(o+(ndx))
+ //#define w(ndx) (signed char)pgm_read_word(w+(ndx))
+//#endif // PC
+
+
+void D(void);
+
+
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+// nein, in dem folgenden Codefragment fusche ich dann nicht mehr rum, es
+// scheint sich dabei um das eigentliche Orginal von H.G. Muller zu handeln,
+// was sowie keiner versteht...
+// F. Menzel: Leider kommen hier diverse Warnings beim Uebersetzen, funktioniert
+// aber durch die Vorrangregeln prima. Mir ist es leider nicht geglückt,
+// die Klammern entsprechend richtig zu setzen, damit die Quelle
+// warnungsfrei wird
+//TODO: Klammernsetzung fuer Warnungsfreiheit
+/* -------------------------------------------------------------------------- */
+/* better readability of working struct variables */
+#define q _.q
+#define l _.l
+#define e _.e
+#define E _.E
+#define z _.z
+#define n _.n
+#define m _.m
+#define v _.v
+#define V _.V
+#define P _.P
+#define r _.r
+#define j _.j
+#define B _.B
+#define d _.d
+#define h _.h
+#define C _.C
+#define u _.u
+#define p _.p
+#define x _.x
+#define y _.y
+#define F _.F
+#define G _.G
+#define H _.H
+#define t _.t
+#define X _.X
+#define Y _.Y
+#define a _.a
+
+
+/* *****************************************************************************
+ * MEL: hier kommen leider lauter Warnungen, ist aber der Originalcode, welcher
+ * wohl mit Absicht genau so geschrieben wurde;
+ * ist mir leider nicht geglueckt, die Klammern an der richtigen Stelle zu setzen
+ * vielleicht kann das ja jemand anderes machen mit tieferem C-Wissen???
+ *******************************************************************************/
+
+
+void D() /* iterative Negamax search */
+{
+
+D:if (--J<A) { /* stack pointer decrement and underrun check */
+ ++J;DD=-l;goto R; /* simulated return */
+ }
+ q=Dq;l=Dl;e=De;E=DE;z=Dz;n=Dn; /* load arguments */
+ a=Da; /* load return address state*/
+
+ --q; /* adj. window: delay bonus */
+ k^=24; /* change sides */
+ d=X=Y=0; /* start iter. from scratch */
+ while(d++<n||d<3|| /* iterative deepening loop */
+ z&K==I&&(timer<0&d<98|| /* root: deepen upto time */
+ (K=X,L=Y&~M,d=3))) /* time's up: go do best */
+ {x=B=X; /* start scan at prev. best */
+ h=Y&S; /* request try noncastl. 1st*/
+ if(d<3)P=I;else
+ {*J=_;Dq=-l;Dl=1-l;De=-e;DE=S;Dz=0;Dn=d-3; /* save locals, arguments */
+ Da=0;goto D; /* Search null move */
+R0:_=*J;P=DD; /* load locals, return value*/
+ }
+ m=-P<l|R>35?d>2?-I:e:-P; /* Prune or stand-pat */
+#ifdef UNIX
+ ++timer; /* node count (for timing) */
+#endif
+ do{u=b[x]; /* scan board looking for */
+ if(u&k) /* own piece (inefficient!)*/
+ {r=p=u&7; /* p = piece type (set r>0) */
+ j=o(p+16); /* first step vector f.piece*/
+ while(r=p>2&r<0?-r:-o(++j)) /* loop over directions o[] */
+ {A: /* resume normal after best */
+ y=x;F=G=S; /* (x,y)=move, (F,G)=castl.R*/
+ do{ /* y traverses ray, or: */
+ H=y=h?Y^h:y+r; /* sneak in prev. best move */
+ if(y&M)break; /* board edge hit */
+ m=E-S&b[E]&&y-E<2&E-y<2?I:m; /* bad castling */
+ if(p<3&y==E)H^=16; /* shift capt.sqr. H if e.p.*/
+ t=b[H];if(t&k|p<3&!(y-x&7)-!t)break; /* capt. own, bad pawn mode */
+ i=37*w(t&7)+(t&192); /* value of capt. piece t */
+ m=i<0?I:m; /* K capture */
+ if(m>=l&d>1)goto J; /* abort on fail high */
+
+ v=d-1?e:i-p; /* MVV/LVA scoring */
+ if(d-!t>1) /* remaining depth */
+ {v=p<6?b[x+8]-b[y+8]:0; /* center positional pts. */
+ b[G]=b[H]=b[x]=0;b[y]=u|32; /* do move, set non-virgin */
+ if(!(G&M))b[F]=k+6,v+=50; /* castling: put R & score */
+ v-=p-4|R>29?0:20; /* penalize mid-game K move */
+ if(p<3) /* pawns: */
+ {v-=9*((x-2&M||b[x-2]-u)+ /* structure, undefended */
+ (x+2&M||b[x+2]-u)-1 /* squares plus bias */
+ +(b[x^16]==k+36)) /* kling to non-virgin King */
+ -(R>>2); /* end-game Pawn-push bonus */
+ V=y+r+1&S?647-p:2*(u&y+16&32); /* promotion or 6/7th bonus */
+ b[y]+=V;i+=V; /* change piece, add score */
+ }
+ v+=e+i;V=m>q?m:q; /* new eval and alpha */
+ C=d-1-(d>5&p>2&!t&!h);
+ C=R>29|d<3|P-I?C:d; /* extend 1 ply if in check */
+ do
+ if(C>2|v>V)
+ {*J=_;Dq=-l;Dl=-V;De=-v;DE=F;Dz=0;Dn=C; /* save locals, arguments */
+ Da=1;goto D; /* iterative eval. of reply */
+R1: _=*J;s=-DD; /* load locals, return value*/
+ }else s=v; /* or fail low if futile */
+ while(s>q&++C<d);v=s;
+ if(z&&K-I&&v+I&&x==K&y==L) /* move pending & in root: */
+ {Q=-e-i;O=F; /* exit if legal & found */
+ R+=i>>7;++J;DD=l;goto R; /* captured non-P material */
+ }
+ b[G]=k+6;b[F]=b[y]=0;b[x]=u;b[H]=t; /* undo move,G can be dummy */
+ }
+ if(v>m) /* new best, update max,best*/
+ m=v,X=x,Y=y|S&F; /* mark double move with S */
+ if(h){h=0;goto A;} /* redo after doing old best*/
+ if(x+r-y|u&32| /* not 1st step,moved before*/
+ p>2&(p-4|j-7|| /* no P & no lateral K move,*/
+ b[G=x+3^r>>1&7]-k-6 /* no virgin R in corner G, */
+ ||b[G^1]|b[G^2]) /* no 2 empty sq. next to R */
+ )t+=p<5; /* fake capt. for nonsliding*/
+ else F=y; /* enable e.p. */
+ }while(!t); /* if not capt. continue ray*/
+ }}}while((x=x+9&~M)-B); /* next sqr. of board, wrap */
+J:if(m>I-M|m<M-I)d=98; /* mate holds to any depth */
+ m=m+I|P==I?m:0; /* best loses K: (stale)mate*/
+ /*if(z&hv&d>2) {
+ print_move('a'+(X&7), '8'-(X>>4), 'a'+(Y&7), '8'-(Y>>4&7));
+ }*/
+ } /* encoded in X S,8 bits */
+ k^=24; /* change sides back */
+ ++J;DD=m+=m<e; /* delayed-loss bonus */
+R:if (J!=A+U) switch(a){case 0:goto R0;case 1:goto R1;}
+ else return;
+}
+
+
+
+/* *****************************************************************************
+ * Ende der Original-Schachroutinen
+ * Beginn der Routinen des Verhaltens und natuerlich Verhalten selbst
+ *******************************************************************************/
+#ifdef PC
+#define OFFSET 240; /*!< Offsetwert, um genau von einer Sim-Schachfeld-Position zur naechsten zu kommen */
+#else
+// fuer MCU anpassen je nach Groesse des echten Schachbrettes
+#define OFFSET 240; /*!< Offsetwert, um genau von einer Sim-Schachfeld-Position zur naechsten zu kommen */
+#endif
+
+static uint8_t state = 0; /*!< Status des Verhaltens */
+
+
+uint8_t white; /*!< Kennung welcher Spieler gerade dran ist, nur Schwarz wird vom Bot gefahren */
+
+
+
+/*!
+ * Umwandeln der Zug-Zeichenstellen in Bot-Worldkoordinaten zum Abfahren des Zuges auf dem Sim-Schachfeld
+ * @param x_c 1. Stelle der Zugangabe (a bei Zug a2)
+ * @param y_c 2. Stelle der Zugangabe (2 bei Zug a2)
+ * @param *wx x-Koordinate fuer Bot-Zielposition
+ * @param *wy y-Koordinate fuer Bot-Zielposition
+ */
+void chess2worldkoords(char x_c, char y_c, int16_t *wx, int16_t *wy) {
+ //aus Klein- Grossbuchstaben machen und Offsetwert zu-/abrechnen
+ *wx=(x_c-97) * -OFFSET; /* nach Rechts x-Richtung, Werte werden negativ und um 1 Offsetfeld verschoben */
+ *wx=*wx-OFFSET
+ *wy=(y_c-49) * OFFSET; /* nach Oben y-Richtung, Werte positiver aber um 1 Offset-Feld verschoben */
+ *wy=*wy+OFFSET;
+}
+
+
+/*!
+ * Aufgerufene Routine nach Taste GO; der eingegebene Zug wird geparst bzw. ein neuer Schachzug ermittelt
+ * Ist die manuelle Zugeingabe erforderlich oder der Zug war nicht gueltig, erscheint auf dem Display ZU G?
+ * Routine wurde etwas von der Original-Schachroutine fuer diese Zwecke abgewandelt, enthaelt aber auch deren
+ * Initialisierungen, die man wohl nicht unbedingt verstehen muss bzw. erklaeren kann:-) Naeheres wohl auf der
+ * o.a. Website
+ * @result Rueckgabe der ausgefuehrten Aktion bzw. Status nach GO
+ * 1: manueller Zug geparst und gueltig;
+ * 2: Zug vom Prog berechnet;
+ * 0: sonst (Zug nicht gueltig)
+ */
+uint8_t chess_go(void) {
+ uint8_t result;
+
+ result =0;
+
+ if(*c-GO) {
+ /* parse entered move */
+ K=*c-16*c[1]+799;
+ L=c[2]-16*c[3]+799;
+ LOG_DEBUG("Zug wurde eingegeben und parsen");
+ } else {
+ K=I;
+ timer = -128<<st; /* set time control */
+ clean_move_digits();
+ LOG_DEBUG("Ich denke...");
+ }
+
+ Dq=-I;Dl=I;De=Q;DE=O;Dz=1;Dn=3; /* store arguments of D() */
+ Da=0; /* state */
+
+ D();
+ if(*c-GO) { // Zugeingabe vorhanden
+ if(I==DD) { // Zug ist gueltig
+ LOG_DEBUG("eing. Zug war gueltig");
+ result = 1;
+ } else { // .. ungueltig
+ print_move('Z', 'U', 'G', '?');
+ LOG_DEBUG("Zug? war nicht gueltig");
+ }
+ *c=GO;
+ } else { // Computerzug
+ result = 2;
+ ++moves; // Zuganzahl erhoehen
+ print_move('a'+(K&7), '8'-(K>>4), 'a'+(L&7), '8'-(L>>4&7)); // Displayausgabe
+ LOG_DEBUG("Computerzug Zug %1d",moves);
+ LOG_DEBUG("Zug aus D() von %c %c nach %c %c",'a'+(K&7), '8'-(K>>4), 'a'+(L&7), '8'-(L>>4&7));
+ if(!(DD>-I+1)){
+ print_move('M', 'A', 'T', 'T'); // Displayausgabe
+ LOG_DEBUG("-- SCHACH MATT! --");
+ }
+ }
+
+ return result;
+}
+
+
+/*!
+ * Initialisierungen fuer neues Spiel
+ * aus Originalquelle uebernommen, naeheres dazu sicher auf o.a. Website
+ */
+void new_game_init(void) {
+
+ LOG_DEBUG("Neues Spiel");
+ print_move ('S', 'H', 'A', 'H');
+
+ k=16;
+ O=Q=R=0;
+ for(W=0; W < sizeof b; ++W) b[W]=0;
+ for(W=0; W < sizeof c; ++W) c[W]=0; // damit beim naechsten Start auch wieder Zugeingabe ausgegeben wird
+ W=8;
+ while(W--) { /* initial board setup*/
+ b[W]=(b[W+112]=o(W+24)+8)+8;
+
+ b[W+16]=18;
+ b[W+96]=9;
+ L=8;
+ while(L--) b[16*L+W+8]=(W-4)*(W-4)+(L+L-7)*(L+L-7)/4; /* center-pts table */
+ } /*(in unused half b[])*/
+
+ W=4;
+ moves=0; // Anzahl Zuege ruecksetzen
+ white=0; // Spieler init.
+}
+
+
+// Status des Verhaltens
+#define NEWGAME_STATE 0
+#define GO_STATE 1
+#define GO_STATE_NEXT 2
+#define CO_END 99
+
+
+/*!
+ * Das eigentliche Schach-Fahrverhalten
+ * Fuer den Bot-Spieler Schwarz wird nach dessen Zugberechnung der Zug vom Bot nachgefahren, fährt also von der Zug-Startposition
+ * zur Zug-Endposition. Das Verhalten ist dann damit abgeschlossen
+ * @param *data Der Verhaltensdatensatz
+ */
+void bot_drive_chess_behaviour(Behaviour_t * data) {
+int16_t wx; // zur Umwandlung des Zuges in Botkoordinaten
+int16_t wy;
+uint8_t res_go; //Status nach GO
+
+ switch (state) {
+ case NEWGAME_STATE:
+ /* Neues Spiel wird gestartet */
+ LOG_DEBUG("-NEWGAME-");
+ state=GO_STATE;
+ new_game_init();
+ break;
+
+
+ case GO_STATE:
+ /* Einsprung fuer GO nach Zugeingabe */
+ LOG_DEBUG("GO STATE");
+ state = CO_END;
+
+ res_go=chess_go();
+
+ if (res_go==1) { // nach man. Zug gleich Computerzug hinterher
+ white=!white;
+ LOG_DEBUG("gleich Compi ziehen lassen, Zug war OK, weiss %1d",white);
+
+ state = GO_STATE; // gleichen Verhaltensstatus aufrufen
+
+ }
+ else {
+ if (res_go==2) {
+ white=!white;
+ if (white) {
+ LOG_DEBUG("Weiss-keine Botbewegung");
+ }
+ else {// nur wenn Schwarz an der Reihe ist bot bewegen
+ LOG_DEBUG("Bot fahren nach Autozug");
+ LOG_DEBUG("Zug aus D() von %c %c nach %c %c",'a'+(K&7), '8'-(K>>4), 'a'+(L&7), '8'-(L>>4&7));
+ chess2worldkoords('a'+(K&7),'8'-(K>>4&7), &wx,&wy);
+ LOG_DEBUG("gehe zu Zug-Startpos %1d,%1d, weiss %1d",wy,wx,white);
+ bot_goto_pos(data,wy,wx,999);
+
+ state=GO_STATE_NEXT;
+ break;
+ }
+ }
+
+ }
+
+ break;
+
+
+
+
+
+ case GO_STATE_NEXT:
+ /* Bot wird zu den Zug-Zielkoordinaten gefahren */
+ chess2worldkoords('a'+(L&7),'8'-(L>>4&7),&wx,&wy);
+ LOG_DEBUG("gehe zu Zug-Zielpos %1d,%1d, weiss %1d",wy,wx,white);
+ bot_goto_pos(data,wy,wx,999);
+
+ state = CO_END; // nach Abfahren Verhaltensende
+
+ break;
+
+
+ default:
+ exit_behaviour(data, SUBFAIL);
+ return;
+ }
+}
+
+
+
+/*!
+ * Neustart des eigentlichen Schach-Fahrverhalten
+ * Fuer den Bot-Spieler Schwarz wird nach dessen Zugberechnung der Zug vom Bot nachgefahren, fährt also von der Zug-Startposition
+ * zur Zug-Endposition. Das Verhalten ist dann damit abgeschlossen
+ * @param *caller Der Verhaltensdatensatz
+ */
+void bot_drive_chess(Behaviour_t * caller) {
+ switch_to_behaviour(caller, bot_drive_chess_behaviour, OVERRIDE);
+ state = NEWGAME_STATE;
+}
+
+
+/*!
+ * Start des Schach-Fahrverhalten nach GO-Betaetigung, d.h. nach Eingabe des Zuges wurde GO betaetigt
+ * @param *caller Der Verhaltensdatensatz
+ */
+void bot_drive_chess_go(Behaviour_t * caller) {
+ switch_to_behaviour(caller, bot_drive_chess_behaviour, OVERRIDE);
+ state = GO_STATE;
+}
+
+
+/*!
+ * Routine fuer manuelle Zugeingabe (Tastaturauswertung)
+ */
+void after_input(void) {
+ if (!(W&1)) //Umwandlung Zahl->Zeichen an je 1. Stelle, also an je ungerader Position
+ c[W] += 'a' - '1'; //W ist hierbei der Digit-Positionszaehler des Digits fuer den Zug
+
+ switch (W) {
+ default:
+ print_move_digit(W, c[W]);
+ ++W;
+ break;
+ case 4: // getkey() anzeigen
+ clean_move_digits();
+ c[0]=c[4];
+ print_move_digit(0, c[0]);
+ W=1;
+ break;
+ case 5: // getkey() nicht anzeigen
+ clean_move_digits();
+ W=0;
+ break;
+ }
+
+}
+
+/*!
+ * Keyhandler fuer das Chess-Verhalten
+ */
+#ifdef DISPLAY_DRIVE_CHESS_AVAILABLE
+static void drivechess_disp_key_handler(void) {
+ switch (RC5_Code) {
+ case RC5_CODE_STOP:
+ /* Newgame */
+ RC5_Code = 0;
+ c[W] = F_NEWGAME;
+ // Verhaltensstart Newgame
+ bot_drive_chess(NULL);
+ break;
+
+ case RC5_CH_PLUS:
+ /* Level veraendern */
+ RC5_Code = 0;
+ c[W] = F_LEVEL;
+ st++;
+ LOG_DEBUG("Level erhoeht auf %1d",st);
+ break;
+
+ case RC5_CH_MINUS:
+ /* Level veraendern */
+ RC5_Code = 0;
+ c[W] = F_LEVEL;
+ st--;
+ LOG_DEBUG("Level verringert auf %1d",st);
+
+ break;
+
+
+ case RC5_CODE_BLUE:
+ /* Zugzeile loeschen */
+ RC5_Code = 0;
+ c[W] = CL;
+ LOG_DEBUG("CLEAR %c",c[W]);
+ after_input();
+ clean_move_digits();
+ W=0;
+ break;
+
+
+
+case RC5_CODE_PLAY:
+ /* GO */
+ RC5_Code = 0;
+ if (W==99) {
+ LOG_DEBUG("vor GO erstmaliges INIT");
+ //new_game_init();
+ bot_drive_chess(NULL);
+ }
+ else {
+ // Verhaltensstart im Status GO
+ bot_drive_chess_go(NULL);
+ }
+ c[W] = GO;
+ break;
+
+default:
+ /* wird immer durchlaufen fuer alle anderen Tasten als oben angegeben */
+ /* hier nur noch die Tasten fuer man. Zugeingabe rauspicken */
+ switch (RC5_Code) {
+ case RC5_CODE_1:c[W]='1';after_input();RC5_Code = 0;break;
+ case RC5_CODE_2:c[W]='2';after_input();RC5_Code = 0;break;
+ case RC5_CODE_3:c[W]='3';after_input();RC5_Code = 0;break;
+ case RC5_CODE_4:c[W]='4';after_input();RC5_Code = 0;break;
+ case RC5_CODE_5:c[W]='5';after_input();RC5_Code = 0;break;
+ case RC5_CODE_6:c[W]='6';after_input();RC5_Code = 0;break;
+ case RC5_CODE_7:c[W]='7';after_input();RC5_Code = 0;break;
+ case RC5_CODE_8:c[W]='8';after_input();RC5_Code = 0;break;
+ case RC5_CODE_9:c[W]='9';after_input();RC5_Code = 0;break;
+ }//switch
+
+ break;
+
+ } // switch
+} // Ende Keyhandler
+
+
+/*!
+ * Display zum Steuern des Schachverhaltens
+ */
+void drive_chess_display(void) {
+ display_cursor(1, 1);
+ display_printf("Chess Level %1d",st);
+ display_cursor(2, 1);
+ display_printf("Zug : %c%c %c%c",d_0,d_1,d_2,d_3);
+ display_cursor(3, 1);
+ display_printf("CL BLUE/Lv CH+-");
+ display_cursor(4, 1);
+ display_printf("Go PLAY/New STOP");
+
+ drivechess_disp_key_handler(); // aufrufen des Key-Handlers
+}
+#endif // DISPLAY_DRIVE_CHESS_AVAILABLE
+
+#endif // BEHAVIOUR_DRIVE_CHESS_AVAILABLE
Index: .cproject
===================================================================
--- .cproject (revision 1618)
+++ .cproject (working copy)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?xml version="1.0" encoding="UTF-8"?>
<?fileVersion 4.0.0?>
<cproject>
@@ -15,7 +15,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-<configuration artifactExtension="exe" artifactName="ct-Bot" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="Windows mit Debug-Code" errorParsers="org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="cdt.managedbuild.config.gnu.exe.debug.1077176217" name="Debug-W32" parent="cdt.managedbuild.config.gnu.exe.debug" postbuildStep="objcopy -j .eeprom --change-section-lma .eeprom=0 -O binary ct-Bot.exe ct-Bot.eep; objdump -t ct-bot.exe | grep "(sec 5)" | grep "(nx 0)" > eeprom_pc.map">
+<configuration artifactExtension="exe" artifactName="ct-Bot" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="Windows mit Debug-Code" errorParsers="org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="cdt.managedbuild.config.gnu.exe.debug.1077176217" name="Debug-W32" parent="cdt.managedbuild.config.gnu.exe.debug" postbuildStep="objcopy -j .eeprom --change-section-lma .eeprom=0 -O binary ct-Bot.exe ct-Bot.eep; objdump -t ct-bot.exe | grep "(sec 5)" | grep "(nx 0)" > eeprom_pc.map">
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1077176217.380212843" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1011694867" name="GCC Tool Chain" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.1735484471" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
Index: ui/available_screens.h
===================================================================
--- ui/available_screens.h (revision 1618)
+++ ui/available_screens.h (working copy)
@@ -48,6 +48,7 @@
#define DISPLAY_DRIVE_STACK_AVAILABLE /*!< Steuerung Stack-Verhalten auf diesem Screen */
#define PATHPLANING_DISPLAY /*!< Display zur Pfadplanung */
#define DISPLAY_LINE_SHORTEST_WAY_AVAILABLE /*!< Steuerung des Verhaltens auf diesem Screen */
+#define DISPLAY_DRIVE_CHESS_AVAILABLE /*!< Steuerung des Schach-Verhaltens */
#ifndef SPEED_CONTROL_AVAILABLE
#undef DISPLAY_REGELUNG_AVAILABLE
Index: Changelog.txt
===================================================================
--- Changelog.txt (revision 1618)
+++ Changelog.txt (working copy)
@@ -1,5 +1,7 @@
CHANGELOG fuer c't-Bot
======================
+2009-05-28 Frank Menzel [Menzelfr@xxxxxx]: Der Bot spielt Schach! Neues Schachverhalten behaviour_drive_chess
+
2009-09-24 Timo Sandmann [mail@xxxxxxxxxxxxxxx]: BPS-Sensordaten des echten Bots werden zum Sim uebertragen
2009-09-23 Timo Sandmann [mail@xxxxxxxxxxxxxxx]: Bugfix im Command-Code, keine Uebertragung der Lichtsensordaten, falls keine Lichtsensoren aktiv sind
Index: include/bot-logic/behaviour_drive_chess.h
===================================================================
--- include/bot-logic/behaviour_drive_chess.h (revision 0)
+++ include/bot-logic/behaviour_drive_chess.h (revision 0)
@@ -0,0 +1,77 @@
+/*
+ * c't-Bot
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307, USA.
+ *
+ */
+
+
+/*!
+ * @file behaviour_drive_chess.c
+ * @brief Der Bot spielt Schach! Das Schachverhalten ermoeglicht die manuelle Eingabe
+ * eines Schachzuges des Spielers 1 (weiss) ueber das Screeninterface. Nach Betaetigen
+ * der GO-Taste zieht der Bot-Spieler und der Bot fährt auf dem Schachbrett diesen
+ * Zug nach. Nun ist der menschliche Spieler wieder am Zug via Screeneingabe bzw. drückt sofort GO,
+ * um fuer sich den Zug machen zu lassen. Am besten ist es (weil ja die Schachfiguren nicht visualisiert werden),
+ * sich parallel dazu ein echtes Schachbrett aufzubauen und manuell die Zuege nachzuvollziehen. In meinem ersten Test
+ * musste ich eine Niederlage gegen den Bot einstecken:-)
+ * Fuer das Verhalten ist das Chess-Layout zu laden, damit wenigstens die Schachfelder visualisiert werden und damit die
+ * Botfahrten der gegnerischen Schachzuege. Die gruenen Felder stehen hierbei stellvertretend fuer die weissen Felder.
+ * Inspiriert zu diesem Verhalten wurde ich durch folgende Seiten:
+ * http://bralug.de/wiki/BLIT2008-Board_spielt_Schach
+ * Detailliertes zu dem Micro-Max Schach ist hier zu finden:
+ * http://home.hccnet.nl/h.g.muller/max-src2.html
+ *
+ * Brainstorming fuer moegliche Erweiterungen:
+ * Der Bot koennte gegen den anderen spielen ohne Mensch, d.h. Bot 1 ist Spieler 1 und der andere der Gegenspieler.
+ * Jeder bot macht jeweils einen Zug und fährt diesen ab. Danach ist der andere dran. Dies muesste/koennte dann ueber die
+ * bot_2_bot-Kommunikation laufen. Noch schoener waere es natuerlich, echte Spielfiguren auf dem Java3D-Schachbrett zu haben
+ * (oder zuerst auch einfache Objekte), wobei der bot sich jeweils die Figur greift (bot_catch_pillar) und an der Zielposition
+ * ablaedt (bot_unload_pillar)...
+ *
+ * @author Frank Menzel (Menzelfr@xxxxxx)
+ * @date 15.09.2009
+ */
+#ifndef BEHAVIOUR_DRIVE_CHESS_H_
+#define BEHAVIOUR_DRIVE_CHESS_H_
+
+#include "ct-Bot.h"
+#include "bot-logic/bot-logik.h"
+
+#ifdef BEHAVIOUR_DRIVE_CHESS_AVAILABLE
+
+/*!
+ * Das eigentliche Schach-Fahrverhalten
+ * Fuer den Bot-Spieler Schwarz wird nach dessen Zugberechnung der Zug vom Bot nachgefahren, fährt also von der Zug-Startposition
+ * zur Zug-Endposition. Das Verhalten ist dann damit abgeschlossen
+ * @param *data Der Verhaltensdatensatz
+ */
+void bot_drive_chess_behaviour(Behaviour_t * data);
+
+/*!
+ * Neustart des eigentlichen Schach-Fahrverhalten
+ * Fuer den Bot-Spieler Schwarz wird nach dessen Zugberechnung der Zug vom Bot nachgefahren, fährt also von der Zug-Startposition
+ * zur Zug-Endposition. Das Verhalten ist dann damit abgeschlossen
+ * @param *caller Der Verhaltensdatensatz
+ */
+void bot_drive_chess(Behaviour_t * caller);
+
+/*!
+ * Display zum Steuern des Schachverhaltens
+ */
+void drive_chess_display(void);
+
+#endif // BEHAVIOUR_DRIVE_CHESS_AVAILABLE
+#endif /*BEHAVIOUR_DRIVE_CHESS_H_*/
Index: include/bot-logic/available_behaviours.h
===================================================================
--- include/bot-logic/available_behaviours.h (revision 1618)
+++ include/bot-logic/available_behaviours.h (working copy)
@@ -60,6 +60,8 @@
//#define BEHAVIOUR_DRIVE_AREA_AVAILABLE /*!< flaechendeckendes Fahren mit Map */
+#define BEHAVIOUR_DRIVE_CHESS_AVAILABLE /*!< Schach fuer den Bot */
+
//#define BEHAVIOUR_LINE_SHORTEST_WAY_AVAILABLE /*!< Linienfolger ueber Kreuzungen zum Ziel */
//#define BEHAVIOUR_SCAN_BEACONS_AVAILABLE /*!< Suchen von Landmarken zur Lokalisierung */
@@ -88,6 +90,10 @@
#endif
#endif
+#ifdef BEHAVIOUR_DRIVE_CHESS_AVAILABLE
+ #define BEHAVIOUR_GOTO_POS_AVAILABLE
+#endif
+
#ifdef BEHAVIOUR_DRIVE_AREA_AVAILABLE
#define BEHAVIOUR_GOTO_POS_AVAILABLE
#define BEHAVIOUR_GOTO_OBSTACLE_AVAILABLE
@@ -276,6 +282,8 @@
#include "bot-logic/behaviour_drive_area.h"
+#include "bot-logic/behaviour_drive_chess.h"
+
#include "bot-logic/behaviour_pathplaning.h"
#include "bot-logic/behaviour_line_shortest_way.h"
Index: ct-Bot.h
===================================================================
--- ct-Bot.h (revision 1618)
+++ ct-Bot.h (working copy)
@@ -79,7 +79,7 @@
//#define MAP_AVAILABLE /*!< Aktiviert die Kartographie */
//#define MAP_2_SIM_AVAILABLE /*!< Sendet die Map zur Anzeige an den Sim */
-//#define SPEED_CONTROL_AVAILABLE /*!< Aktiviert die Motorregelung */
+#define SPEED_CONTROL_AVAILABLE /*!< Aktiviert die Motorregelung */
//#define ADJUST_PID_PARAMS /*!< macht PID-Paramter zur Laufzeit per FB einstellbar */
//#define SPEED_LOG_AVAILABLE /*!< Zeichnet Debug-Infos der Motorregelung auf MMC auf */
Index: ui/gui.c
===================================================================
--- ui/gui.c (revision 1618)
+++ ui/gui.c (working copy)
@@ -299,7 +299,10 @@
#ifdef BEHAVIOUR_LINE_SHORTEST_WAY_AVAILABLE
register_screen(&bot_line_shortest_way_display);
#endif
+ #ifdef DISPLAY_DRIVE_CHESS_AVAILABLE
+ register_screen(&drive_chess_display);
#endif
+ #endif
}
#endif // DISPLAY_AVAILABLE