/* 21 */ /* Juergen Galupki http://galupki.de */ #define TRUE -1 #define FALSE 0 #define JA -1 #define NEIN 0 #define schwarz -1 #define weiss 1 #define schwarzdran farbe%=schwarz #define weissdran farbe%=weiss #define homeschwarz 25 #define homeweiss 26 #define barschwarz 27 #define barweiss 28 #define normalwurf 2 #define doublette 4 #define muss 1 #define kann 0 #define zugnum zindex% #define zugkm(zugnum) z%((5*zugnum-5)+1) /* Zug kann oder muss */ #define zugvon(zugnum) z%((5*zugnum-5)+2) /* von Point... */ #define zugwind(zugnum) z%((5*zugnum-5)+3) /* mit w%(...) Schritten */ #define zugnach(zugnum) z%((5*zugnum-5)+4) /* nach Point ... */ #define zugvorgnr(zugnum) z%((5*zugnum-5)+5) /* VorgaengerZug ... */ /* ------------------------------------------------------------------------ */ Global farbe% /* schwarz oder weiss */ Global b%(28) /* Backgammonbrett 1-24 negativ Schwarz, positiv weiss, 0 leer Pos 25-28 Home Schwarz, weiss Bar schwarz, weiss */ Global zindex% /* akt. bearbeiteter Zug */ Global z%(2000) /* ermittelte Zuege (400 *5 Positionen = 2000 *2 Bytes = 4Kb) */ Global znr%(4) /* ausgewaehlte Zuege */ Global zuege% /* Anzahl in znr%() */ Global newp% /* Zielposition (zugok%:) */ Global LastZNr% /* letzte Zugnummer (zugauf:) */ Global anzZ% /* anzahl der gesammelten Zuege Gesamt */ Global w%(4) /* Wuerfelergebnisse 1-6 oder 0 */ Global wa% /* Anzahl Ergebnisse (2/4) */ Global wt%(4) /* ------------------------------------------------------------------------ */ farbe% = (-1 schwarz +1 weiss) wuerfeln: wa% = 2 oder 4 2 oder 4 Zuege nach Wuerfeln w%(1-2/4) = Wuerfelergebnisse enthaelt die Wuerfelschritte zuegeE: /* ermitteln moeglicher zuege */ /* ------------------------------------------------------------------------ */ PROC zuegeE: /* ermitteln aller moeglichen Zuege anzZ% */ Local i%, i1%, i2%, i3%, i4% Local barzn% /* Anzahl der min. zu setzenden Barzuege */ Local mbarz% /* Muss-Bar-Zuege */ anzZ% = 0 /* gefundene Zuege insgesamt */ barzn% = MIN(wa%,ABS(b%(BarP%:))) /* Minimum aus Wurfanzahl und BarSteinen */ if barzn% > 0 AND closedB%: /* bei ClosedBoard und Bar geht nix */ RETURN endif /* moegliche bar-zuege ermitteln - von diesen zuegen "muessen" barzn% Zuege gemacht werden ! */ i% = 1 WHILE i% <= barzn% /* pro MenAufBar (abtragbar)*/ if wa% = 2 /* wenn keine doublette */ i1% = 1 WHILE i1% <= 2 /* beide zuege testen */ if zugok%:( BarP%:, farbe%, w%(i1%) ) zugauf:(muss, BarP%:, i1%, newp%, 0) endif i1% = i1% + 1 : ENDWH else /* doublette - */ if zugok%:( BarP%:, farbe%, w%(1) ) /* nur EIN check noetig */ zugauf:(muss, BarP%:, 1, newp%, 0) endif endif i% = i% + 1 : ENDWH if barzn% > 0 AND anzZ% = 0 /* Bar ohne Moeglichkeit */ RETURN endif /* andere moegliche zuege des ursprungsbretts ermitteln */ i% = 1 WHILE i% <= 24 /* fuer jeden point */ if SGN%:( b%(i%) ) = farbe% /* wenn steine von der farbe des spielers da sind */ i1% = MIN(wa%, ABS(b%(i%))) /* anzahl bewegliche steine */ i2% = 1 WHILE i2% <= i1% /* fuer jeden bewegbaren stein*/ if wa% = 2 /* wenn keine doublette */ i3% = 1 WHILE i3% <= 2 /* beide zuege testen */ if zugok%:( i%, farbe%, w%(i3%) ) zugauf:(kann, i%, i3%, newp%, 0) endif i3% = i3% + 1 : ENDWH else /* bei doublette ist nur EIN check noetig */ if zugok%:( i%, farbe%, w%(1) ) zugauf:(kann, i%, 1, newp%, 0) endif endif i2% = i2% + 1 : ENDWH endif i% = i% + 1 : ENDWH /* ermitteln der zuege, die durch erneutes weitersetzen von bereits gesetzten steinen entstehen dazu werden die ursprungsbrettzuege einzeln durchgegangen */ if barzn% < 2 OR wa% = 4 /* weitermachen nur sinnvoll wenn noch */ i% = 1 /* zuege _ausser_ barzuegen da sind ! */ i1% = anzZ% WHILE i% <= i1% /* anzahl der _bisher_ ermittelten zuege */ zindex% = i% if zugnach(zugnum) < 25 /* bisher noch nicht rausgewuerfelt */ if wa% = 2 /* zunaechst fuer normale wuerfe */ tst% = zugnach(zugnum) if zugok%:( tst%, farbe%, w%(gegzug%:(zugwind(zugnum))) ) zugauf:(kann, tst%, gegzug%:(zugwind(zugnum)), newp%, zindex%) endif else /* oder fuer doubletten die restlichen 3 zugmoeglichkeiten */ tst% = zugnach(zugnum) if zugok%:( tst%, farbe%, w%(2) ) zugauf:(kann, tst%, 2, newp%, zindex%) /* abh. zug Nr. 2 */ if newp% < 25 tst% = newp% i2% = anzZ% if zugok%:( tst%, farbe%, w%(3) ) zugauf:(kann, tst%, 3, newp%, i2%) /* abh. zug Nr. 3 */ if newp% < 25 tst% = newp% i2% = anzZ% if zugok%:( tst%, farbe%, w%(4) ) zugauf:( kann, tst%, 4, newp%, i2%) /* abh. zug Nr. 4 */ endif /* dritter Folgezug */ endif endif /* zweiter Folgezug */ endif endif /* erster Folgezug */ endif /* normal oder doublette */ endif /* nicht rausgewuerfelt */ i% = i% + 1 : ENDWH /* ursprungsbrettzuege */ endif /* zuege variieren aus der vorher aufgestellten zugliste. sind men auf dem bar ( barzn% > 0 ) muessen mbarz Zuege von den MUSS Zuegen ausgefuehrt werden, die restlichen von den KANN Zuegen... sind abhaengige zuege dabei, muessen alle vorgaengerzuege bei der akt. auswahl vorhanden sein... */ zuege% = 0 mbarz% = MIN(barzn%, wa%, anzZ%) /* MUSS-Anzahl */ IF anzZ% > 0 i% = anzZ% i1% = 1 WHILE i1% <= i% znr%(1) = i1% zuege% = 1 i2% = MIN( i%, i1% + 1) WHILE i2% <= i% IF i1% <> i2% znr%(2) = i2% zuege% = 2 endif /* zweiter zug */ if wa% = 2 /* normaler wurf - zwei zuege gefunden oder Ende der Fahnenstange */ zugtst: else /* doublette - dann koennen noch zuege folgen... */ i3% = MIN(i%, i2% + 1) WHILE i3% <= i% if i3% <> i1% AND i3% <> i2% znr%(3) = i3% zuege% = 3 endif i4% = MIN(i%, i3% + 1) WHILE i4% <= i% if i4% <> i1% AND i4% <> i2% AND i4% <> i3% znr%(4) = i4% zuege% = 4 endif /* doublette - 1-4 Zuege gefunden... */ zugtst: i4% = i4% + 1 : ENDWH i3% = i3% + 1 : ENDWH endif /* doublette bzw. normaler wurf */ i2% = i2% + 1 : ENDWH i1% = i1% + 1 : ENDWH ENDIF ENDP PROC zugtst: Local i%, i1%, i2%, ok% wt%(1) = NEIN wt%(2) = NEIN i1% = 0 /* Bar-Zuege ist */ i% = 1 WHILE i% <= zuege% zindex% = znr%(i%) wt%(zugwind(zugnum)) = JA if zugvorgnr(zugnum) > 0 ok% = NEIN i2% = 1 WHILE i2% <= zuege% if znr%(i2%) = zugvorgnr(zugnum) ok% = JA BREAK endif i2% = i2% + 1 : ENDWH if ok% = NEIN RETURN /* vorausgesetzter Zug ist nicht da */ endif endif if zugkm(zugnum) = muss i1% = i1% + 1 /* Bar-Zuege ist */ endif i% = i% + 1 : ENDWH if mbarz% > 0 /* Bar-Zuege soll */ if i1% > mbarz% RETURN /* zu viele Barzuege ausgewaehlt */ endif if i1% = 0 RETURN /* gar kein Barzug ausgewaehlt */ endif endif if zuege% = 2 AND wa% = 2 if wt%(1) = NEIN OR wt%(2) = NEIN RETURN /* nicht 2 verschiedene Zuege */ endif endif anzahl der moeglichen zuege merken: 1. anzahl der wuerfel muessen gesetzt werden wenn moeglich 2. wenn nur XOR einer moeglich dann der hoehere ENDP PROC closedB%: IF farbe% = -1 /* schwarz dran - weisses homefeld zu ? */ RETURN b%(19) > 1 AND b%(20) > 1 AND b%(21) > 1 AND b%(22) > 1 AND b%(23) > 1 AND b%(24) > 1 ELSE /* weiss dran - schwarzes homefeld zu ? */ RETURN b%(1) < -1 AND b%(2) < -1 AND b%(3) < -1 AND b%(4) < -1 AND b%(5) < -1 AND b%(6) < -1 ENDIF ENDP PROC zugok%:( akt%, farbe%, schritt% ) liefert TRUE oder FALSE zurueck, wenn die ANzahl Schritte w%(zugindex) vom Point akt% aus mit der farbe% gemacht werden koennen Die Globale Variable newp% wird korrekt gesetzt ! if akt% < 1 OR akt% > 28 newp% = akt% RETURN FALSE ENDIF IF farbe% = -1 schwarz geht immer vorwaerts (klein nach gross) if akt% = 27 newp% = schritt% einsetzen vom bar else newp% = akt% + schritt% weitersetzen auf Brett endif if newp% > 24 newp% = 25 home sweet home RETURN TRUE else if b%(newp%) < 2 RETURN TRUE kein stein oder EIN weisser stein oder schwarz else RETURN FALSE enemy endif endif ELSE weiss geht immer rueckwaerts (gross anch klein) if akt% = 28 newp% = 25 - schritt% einsetzen vom bar else newp% = akt% - schritt% weitersetzen auf Brett endif if newp% < 1 newp% = 26 home sweet home RETURN TRUE else if b%(newp%) > -2 RETURN TRUE kein stein oder EIN schwarzer stein oder weiss else RETURN FALSE enemy endif endif ENDIF ENDP PROC zugauf:(km%, von%, zugi%, nach%, zugn%) vermerkt in der "moeglichen Zugliste" die Infos und erhoeht anzZ% um eins km% muss = Barzug = 1, kann = "Feld"Zug = 0 von% von wo gehts los 1-28 zugi% welcher Wuerfel (1-4) nach% neue (ziel-)positon des steins, wenn gesetzt wurde zugn% 0=zug aus urspruenglicher Position, n=zug aufbauend auf vorherigem zug n anzZ% = anzZ% + 1 zi% = (5*anzZ%-5) z%(zi%+1) = km% z%(zi%+2) = von% z%(zi%+3) = zugi% z%(zi%+4) = nach% z%(zi%+5) = zugn% ENDP PROC SGN%:(signum%) Signum der Zahl (negativ -1 positiv +1 oder 0) if signum% < 0 return -1 elseif signum% > 0 return +1 else return 0 endif ENDP PROC gegzug%:( zugind% ) zweiter Zug if zugind% = 1 RETURN 2 else RETURN 1 endif ENDP PROC BarP%: if farbe% = -1 return 27 else return 28 endif ENDP Distribution. Distribution is how evenly your checkers are divided among the points occupied. It is usually better to have 3 checkers each on two different points rather than 4 checkers one and 2 on the other. You should rarely have six checkers on a point and almost never have any more. A player with even distribution will seemingly get "luckier" dice than his less flexible opponent. Exposure. Don't be afraid to leave shots early in the game to establish a strong offense or defense. Be more cautious as your enemy's home board gets stronger. The more points he has in his home board, the more difficult it will be for you to re-enter after being hit. Conversely, the more points that you control in your enemy's home board (anchors) the bolder you may play. Even if his board is weak, limit the number of blots (single checkers) to no more than four. If you are significantly ahead in the race or position, then restrict your exposure to maintain your lead. Blocking and Priming. Try to build points without gaps between them directly in front of the enemy checkers in your home board to prevent their escape. Establishing these critical points as early as possible in approximate order of importance: 5, 4, 7 to start your blockade. Six points in a row is called a prime. This makes it impossible for your opponent to escape for as long as you can maintain that structure. Hitting. Try to hit checkers that are the most advanced or checkers that your opponent would like to cover to establish an important point. Attack only when it is advantageous to do so. For example, if you already have two enemy checkers on the bar, it is more critical to make another point in your home board than to hit a third checker. Also refrain from hitting if it makes you more vulnerable than your opponent. Keep your objectives in mind and don't be side-tracked. However, there is an old backgammon adage that still carries weight, "When in doubt, hit." Anchoring. Anchoring is establishing a defensive point (anchor) in your enemies home board. This gives you a landing spot to come in on should you get hit and prevents your opponent from making his home board. Early in the game try to establish anchors on the higher points (20,21). If you become significantly behind in the race, the lower points (22,23,24) have more value as your strategy is to build your home board and wait for a shot. If you have two anchors try to keep them on adjacent points. FIBS Ratings FIBS Rating Formula [From the FIBS man pages.] NAME formula - The formulas used to calculate rating changes DESCRIPTION These are the formulas used to determine the ratings of a player: Let's say that two players P1 and P2 were playing a n-point match. The ratings of the players are r1 for P1 and r2 for P2 . Let D = abs(r1-r2) (rating difference) Let P_upset = 1/(10^(D*sqrt(n)/2000)+1) (probability that underdog wins) Let P=1-P_upset if the underdog wins and P=P_upset if the favorite wins. For the winner: Let K = max ( 1 , -experience/100+5 ) The rating change is: 4*K*sqrt(n)*P For the loser: Let K = max ( 1 , -experience/100+5 ) The rating change is: -4*K*sqrt(n)*P The 'experience' of a player is the sum of the lengths of all matches a player has finished. Every player starts with a rating of 1500 and an experience of 0. SEE ALSO ratings WHILE augen gleich wrfel weiss wrfel schwarz farbe (am zug) = max(ww, ws) WHILE pipsW > 0 AND pipss > 0 zug(farbe). *** zug(farbe): IF NOT eroeffnung wuerfeln IF men auf bar(farbe) AND closedBoard aussetzen ELSE moegliche zuege ermitteln IF computer dran evaluator besten zug setzen ELSE zug entgegennehmen IF hilfe-zug evaluator besten zug vorschlagen zug entgegennehmen IF doppelwuerfel(farbe) verdoppeln pruefen/vorschlagen *** moegliche zuege ermitteln: WHILE men auf bar(farbe) men einsetzen zuege IF eroeffnunmgsphase bibliothek ELSE sonstige zugmoeglichkeiten *** static evaluator: phasen: eroeffnung points run rollout away je nach Phase unterschiedliche gewichtung der nachfolgenden bewertungen... * anzahl pips 0..162 < (schritte bis ende) * anzahl points 0..7 > * nachbarpoints 0..6 > * verteilung geichmaessig (groessere Luecken schlecht) berz„hlige men auf points * wichtigepoints > * blots 0..15 < gegner-home-feld geschlossen ? * possible hits ? * men inner home 0..15 > * gegnermen auf bar > * distanz zum naechsten point <> *** wichtige Points 4, 5, 7, 20 Blot-Treffwahrscheinlichkeit 1 31 2 33 3 39 4 42 5 42 6 47 7 17 8 17 9 14 10 8 11 6 12 8