allt.cl Page 1 of 17 Date: torsdag 7 december 2006



Relevanta dokument
Uppgift 6A - Frekvenstabell

Projektdokumentation för Othello

Uppgift 4A - Definition av enkla funktioner

Dagens föreläsning Programmering i Lisp Fö 5

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson 2

Tentamen i. TDDC67 Funktionell programmering och Lisp

Imperativ programmering. Imperativ programmering konstruktioner i Lisp. Datastrukturer (kap ) arraystruktur poststruktur

Dagens föreläsning Programmering i Lisp. - Bindning av variabler (avs 14.6) fria variabler statisk/lexikalisk och dynamisk bindning

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson

TDDC74 Programmering, abstraktion och modellering DUGGA 2

Dagens föreläsning. Diverse Common Lisp. Konstanter, parametrar, globala variabler

Två fall: q Tom sekvens: () q Sekvens av element: (a b c) ; (sum-rec '(2 4 6)) = 12. q Första elementet uppfyller vissa villkor: (2 a b c)

n Detta för att kunna koncentrera oss på n Tal: number? n Symboler: symbol? n Strängar: string? n Tecken: char? n Boolskt: boolean?

Rekursiva algoritmer sortering sökning mönstermatchning

TDDC74 Lab 02 Listor, sammansatta strukturer

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Exempelduggan. Luffarschack. Koda spel

Idag: Par och listor. Scheme. DA2001 (Föreläsning 6) Datalogi 1 Hösten / 29

Idag: Par och listor. Symboler. Symboler används för att uttrycka icke-numeriska data såsom namn, adress, bilregisternummer, boktitel, osv.

TENTAMEN I PROGRAMSPRÅK -- DVG C kl. 08:15-13:15

TDDC74 Programmering: Abstraktion och modellering Dugga 2, Tid: kl 08-10, Datum:

Datalogi, grundkurs 1

TDDC74 Programmering, abstraktion och modellering. Tentamen

TDDC74 Programmering, abstraktion och modellering. Tentamen

Dagens föreläsning Programmering i Lisp Fö 7. Sammanfattning funktionell programmering Exempel på funktionella programspråk

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Lösningsförslag. TDDC74 Programmering: Abstraktion och modellering. Dugga 3 (provkod TEN1), Tid: kl 14-16, Datum:

Genetisk programmering i Othello

TDDC74 Programmering: Abstraktion och modellering Tenta, kl 14 18, 11 juni 2014

TDDC74 Programmering, abstraktion och modellering DUGGA 3

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

TDDC74 Programmering: Abstraktion och modellering Datordugga 2 - exempel

Fyra i rad Javaprojekt inom TDDC32

Abstrakta datatyper. Dagens föreläsning. Abstract data types (ADT)

Dagens föreläsning. TDDC67 Funktionell programmering och Lisp Fö 8 och 9

Datalogi, grundkurs 1. Lösningsförslag till tentamen

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 08-12

Symbolisk data. quote. (define a 1) (define b 2) (jacek johan david) (list a b)

Kort Sammanfattning av Schack MAS

Datalogi, grundkurs 1. Lösningsförslag till tentamen

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson

TDDC74 Programmering: Abstraktion och modellering Dugga 2, kl 8 10, 5 mars 2015

TDDC74 Programmering: Abstraktion och modellering Dugga 2, , kl 14-16

TDDC74 Programmering, abstraktion och modellering. Tentamen

TDDC74 - Lektionsmaterial C

Tentamen i Grundläggande Programvaruutveckling, TDA548

TDDC74 Programmering: Abstraktion och modellering. Provkod TEN1, Tid: kl 14-18, , Kåra

TDDC74 Programmering, abstraktion och modellering. Tentamen

Programmering II (ID1019) :00-11:00

TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 29 augusti 2015, kl 8 12

Sökning och sortering. Sökning och sortering - definitioner. Sökning i oordnad lista. Sökning med vaktpost i oordnad lista

Föreläsning 9 Exempel. Intervallhalveringsmetoden. Intervallhalveringsmetoden... Intervallhalveringsmetoden...

Quicksort. Koffman & Wolfgang kapitel 8, avsnitt 9

Sökning och sortering

Utförliga regler för TRAX

Föreläsning 9 Exempel

HI1024 Programmering, grundkurs TEN

Funktionell programmering DD1361

TDDC74 Programmering, abstraktion och modellering DUGGA 2

Tentamen TEN1 HI

Signalflödesmodellen. Två (gamla) exempel: Kvadratera alla jämna löv.

Sagaforms spelregler SCHACK, FIA MED KNUFF, BACKGAMMON, DOMINO

Datalogi, grundkurs 1

Komma igång med Allegro Common Lisp

PROGRAMMERING-JAVA TENTAMINA

TDDC74 Programmering: Abstraktion och modellering Dugga 2, , kl 17-19

TDDC74 Programmering: Abstraktion och modellering Datortenta

TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 9 juni 2016, kl 14 18

TDDC74 Lab 04 Muterbara strukturer, omgivningar

Arrayer (fält)

Sökning i ordnad lista. Sökning och sortering. Sökning med vaktpost i oordnad lista

Tentamen, EDA501/EDAA20 Programmering M MD W BK L

Institutionen för datavetenskap, DAT060, Laboration 2 2 För denna enkla simulerings skull kommer handen att representeras som ett par tal μ värdet på

Några saker till och lite om snabbare sortering

Börja med att kopiera källkoden till din scheme-katalog (som du skapade i Laboration 1).

Ändringsbar (mutable compound) data. TDDC74 Programmering: abstraktion och modellering. Sätta - samman listor kopiering. Hitta sista cons-cellen

Föreläsningsanteckningar F6

String [] argv. Dagens Agenda. Mer om arrayer. Mer om arrayer forts. String [] argv. argv är variabelnamnet. Arrayer och Strängar fortsättning

PROGRAMMERING-Java Omtentamina

Datalogi, grundkurs 1

Institutionen för datavetenskap

Datastrukturer. Föreläsning Innehåll. Program med vektor Exempel. Deklarera vektorer

Visual Basic, en snabbgenomgång

Handbok Othello. Clay Pradarits Utvecklare: Mario Weilguni Granskare: Lauri Watts Översättare: Stefan Asserhäll

Språket Scheme. DAT 060: Introduktion till (funktions)programmering. DrScheme. uttryck. Jacek Malec m. fl. evaluering av uttryck.

Sista delen av kursen

Programspråkslingvistik. Sista delen av kursen. Ett programspråk

Programmeringsuppgift Game of Life

Kravspecifikation. Sammanfattning. Fyra i rad Javaprojekt inom TDDC32. Version 2.0. Datum Dokumentnummer

TENTAMEN PROGRAMMERING I JAVA, 5P SOMMARUNIVERSITETET

Datalogi, grundkurs 1 Övningsuppgifter i Scheme. Serafim Dahl, Carina Edlund, m.fl.

Uppgift 1 ( Betyg 3 uppgift )

PROGRAMMERING-Java TENTAMINA

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Felsökning. Datatyper. Referenstyper. Metoder / funktioner

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Programmering för språkteknologer II, HT2011. Rum

TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 27 augusti 2016, kl 8 12

Anteckningar propp SMT2

729G04 Programmering och diskret matematik. Föreläsning 7

Kungar och Skatter. 2. Ta sedan de fyra essen och blanda dem och lägg sedan slumpvis ut ett ess uppvänt i varje hörn (se fig 2).

Dagens föreläsning. Modeller för programmeringsspråk. - Olika modeller programspråk Interpretator - kompilator. - Syntax - semantik.

Transkript:

allt.cl Page 1 of 17 Slumpspelaren Väljer slumpvis en flytt ur möjliga flyttar. (defun skapa-slump-spelare (namn bricktyp) "lisp-sträng x bricka -> spelare" (skapa-spelare #'slump-gör-flytt namn bricktyp)) (defun slump-gör-flytt (spelplan spelare möjliga) "spelplan x spelare x flyttar -> flytt" (nth-flytt (random (antal-flyttar möjliga)) möjliga)) AI-spelaren (defun skapa-ai-spelare (namn bricktyp) "lisp-sträng x bricka -> spelare" (skapa-spelare #'ai-gör-flytt namn bricktyp)) Låt AI:t (dvs algoritmen giv-bästa-flytt nedanför) ge en flytt. Standarddjup är 3. (defun ai-gör-flytt (spelplan spelare möjliga) "spelplan x spelare -> flytt" (giv-bästa-flytt spelplan (bricktyp spelare) 3)) (defun möjliga-spelplaner (spelplan flyttar bricka) "spelplan x flyttar x bricka -> lisp-lista av spelplan" (mapflyttar flyttar (lambda (flytt) (kopierad-spelplan-med-flytt spelplan bricka flytt)))) Värdera spelplan Möjligheter: 1. Andelen av ens egna brickor/motspelarens brickor. OK! 2. Ta hänsyn till att hörn/kanter är mer värda. OK! 3. Ta hänsyn till vem som har vunnit. Om det är bricka, bra, annars argh.ok! 4. Mer? (defun värdera-specifik-spelplan (spelplan bricka) "spelplan x bricka -> lisp-bråktal" (let* ((mina-brickor (räkna-brickor spelplan bricka)) (fiende-brickor (räkna-brickor spelplan (annan-bricka bricka))) (mina-kanter (antal-kantbrickor spelplan bricka)) (fiende-kanter (antal-kantbrickor spelplan (annan-bricka bricka))) (mina-hörn (antal-hörnbrickor spelplan bricka)) (fiende-hörn (antal-hörnbrickor spelplan (annan-bricka bricka)))) (+ (/ mina-brickor (+ fiende-brickor mina-brickor)) (if (har-någon-vunnit? spelplan) (if (samma-bricka? (vem-leder? spelplan) bricka) 100000-100000) 0) (if (= (+ fiende-kanter mina-kanter) 0) 0 (* 80 (/ mina-kanter (+ fiende-kanter mina-kanter)))) (if (= (+ fiende-hörn mina-hörn) 0) 0 (* 200 (/ mina-hörn (+ fiende-hörn mina-hörn)))) ))) Värderar spelplan(er) i ett visst djup (räknare) returnerar ett värde för hur bra en viss spelplan är ur hänsyn som tas ovan. (defun värdera-spelplan (spelplan bricka räknare)

allt.cl Page 2 of 17 (let ((kan-inte-bricka-a (kan-inte-bricka-lägga? spelplan bricka)) (kan-inte-bricka-b (kan-inte-bricka-lägga? spelplan (annan-bricka bricka)))) (cond ((or (<= räknare 0) (har-någon-vunnit? spelplan) (and kan-inte-bricka-a kan-inte-bricka-b)) (värdera-specifik-spelplan spelplan bricka)) (kan-inte-bricka-b (värdera-spelplan (kopierad-spelplan-med-flytt spelplan bricka (giv-bästa-flytt spelplan bricka (1- räknare))) bricka (1- räknare))) (t (värdera-spelplan (kopierad-spelplan-med-flytt spelplan bricka (giv-bästa-flytt spelplan (annan-bricka bricka) (1- räknare))) (annan-bricka bricka) (1- räknare)))))) Värdera en lista av spelplaner. (defun värdera-massor (spelplaner bricka räknare) (mapcar (lambda (plan) (värdera-spelplan plan bricka räknare)) spelplaner)) Ingång för att utvärde en spelplan. räknare-argumentet bestämmer hur djupt funktionen ska gå när den utvärderar möjliga spelplaner. (defun giv-bästa-flytt (spelplan bricka räknare) (let* ((möjliga (möjliga-flyttar spelplan bricka)) (spelplaner (möjliga-spelplaner spelplan möjliga bricka)) (värderingar (värdera-massor spelplaner bricka räknare))) (format t "värderingar: ~A, räknare: ~A~%" värderingar räknare) ; (format t "FICK DENNA SPELPLAN: ~%") ; (skriv-spelplan spelplan (skapa-flyttar)) ; (format t "GICK IGENOM DESSA SPELPLANER: ~%") ; (mapc (lambda (plan) (skriv-spelplan plan (skapa-flyttar))) spelplaner) (nth (position (reduce #'max värderingar) värderingar) möjliga))) (defun skapa-bricka (namn) "symbol -> bricka" (typkontroll namn #'symbolp) (packa-ihop 'bricka namn)) (defun bricka? (objekt) "lisp-objekt -> sanningsvärde" (eq (typ objekt) 'bricka)) (defun bricka-typ (bricka) "bricka -> symbol" (typkontroll bricka #'bricka?) (packa-upp bricka)) (defun samma-bricka? (b1 b2) "bricka x bricka -> sanningsvärde" (if (eq (bricka-typ b1) (bricka-typ b2)) t nil))

allt.cl Page 3 of 17 (defun annan-bricka (bricka) "bricka -> bricka" (typkontroll bricka #'bricka?) (if (bricka-vit? bricka) (skapa-bricka 'svart) (skapa-bricka 'vit))) (defun bricka-svart? (bricka) "bricka -> sanningsvärde" (typkontroll bricka #'bricka?) (eq (bricka-typ bricka) 'svart)) (defun bricka-vit? (bricka) "bricka -> sanningsvärde" (typkontroll bricka #'bricka?) (eq (bricka-typ bricka) 'vit)) (defun ingen-bricka? (bricka) (null bricka)) Samma-bricka? med rutiner för att kontrollera ifall någon bricka inte är en bricka (t ex från en tom plats på spelplanen.) (defun säker-samma-bricka? (bricka1 bricka2) "bricka x bricka -> sanningsvärde" (if (or (ingen-bricka? bricka1) (ingen-bricka? bricka2)) nil (samma-bricka? bricka1 bricka2))) Standardfunktioner för typerna flytt och flyttar. (defun skapa-flytt (punkt) "punkt -> flytt" (typkontroll punkt #'punkt?) (packa-ihop 'flytt punkt)) (defun flytt? (objekt) "Lisp-objekt -> sanningsvärde" (eq (typ objekt) 'flytt)) (defun punkt (flytt) "flytt -> punkt" (typkontroll flytt #'flytt?) (packa-upp flytt)) (defun skapa-flyttar () "-> flyttar" (list)) (defun antal-flyttar (flyttar) "flyttar -> lisp-heltal" (length flyttar)) (defun lägg-ihop-flyttar (&rest flyttarlist) "flyttar x... x flyttar -> flyttar" (apply #'append flyttarlist)) (defun samma-flytt? (fl1 fl2) "flytt x flytt -> sanningsvärde" (samma-punkt? (punkt fl1) (punkt fl2))) (defun mapflyttar (flyttar fn) "flyttar x funktionsreferens -> flyttar" (mapcar fn flyttar)) (defun nth-flytt (nr flyttar) "flyttar -> flytt" (nth nr flyttar)) (defun filtrera-bort-flytt (flyttar flytt) "flyttar x flytt -> flyttar" (remove-if (lambda (e) (equal e flytt)) flyttar))

allt.cl Page 4 of 17 (defun lägg-till-flytt (flyttar flytt) "flyttar x flytt -> flyttar" (cons flytt flyttar)) (defun första-flytt (flyttar) "flyttar -> flytt" (first flyttar)) (defun resten-flyttar (flyttar) "flyttar -> flyttar" (rest flyttar)) (defun tom-flyttar? (flyttar) "flyttar -> sanningsvärde" (endp flyttar)) Kollar ifall en flyttar innehåller en viss flytt. (defun flyttar-innehåller? (flyttar flytt) "flyttar x flytt -> sanningsvärde" (member-if (lambda (e) (equal e flytt)) flyttar)) En funktion som rensar ut alla dubletter ur en flyttar. (defun unika-flyttar (lista) "flyttar -> flyttar" (if (endp (rest lista)) lista (reduce (lambda (x y) (if (listp (first x)) (if (find-if (lambda (e) (samma-flytt? e y)) x) x (cons y x)) (if (samma-flytt? x y) (list x) (list x y)))) lista))) (setf alfabet "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ") Flyttindex är en kvasityp som egentligen bara är ett heltal. (defun flyttindex-från-beteckning (beteckning flyttar) "lisp-sträng x flyttar -> lisp-heltal" (if (equal beteckning "") (random (antal-flyttar flyttar)) (search (format nil "~a" beteckning) alfabet))) På stora planer kan mängder möjliga flyttar bli för lång (för vårt alfabet) den här funktionen begränsar antalet till längden av alfabetet. (defun begränsa-flyttar (flyttar) "flyttar -> flyttar" (if (> (length flyttar) (length alfabet)) (subseq flyttar 0 (length alfabet)) flyttar)) (defun fråga-efter-spelplan () "-> spelplan" (skapa-spelplan-med-brickor (fråga-efter-nummer "Brädets bredd") (fråga-efter-nummer "Brädets höjd"))) (defun fråga-efter-spelare (antal bricktyp) "Lisp-nummer x bricktyp -> spelarlista" (let ((nybricktyp (if (bricka-vit? bricktyp) (skapa-bricka 'svart) (skapa-bricka 'vit)))) (if (= antal 0) (skapa-spelarlista) (lägg-till-spelare (fråga-efter-spelare (- antal 1) nybricktyp) (funcall (fråga-efter-spelartyp (börja-spelar-input nybricktyp)) (fråga-efter-spelarnamn nybricktyp) bricktyp)))))

allt.cl Page 5 of 17 (defun fråga-efter-spelarnamn (bricktyp) "bricka -> lisp-sträng" (fråga-efter-sträng "Spelarnamn")) (defun fråga-efter-spelartyp (x) "-> funktion" (let ((funktion (skapnings-funktion-från-spelartypssträng (fråga-efter-sträng "Spelartyp")))) (if funktion funktion (progn (format t "Felaktig spelartyp. Måste vara m[änniska], d[ator] eller s[lump].~%") (fråga-efter-spelartyp x))))) (defun skapnings-funktion-från-spelartypssträng (sträng) "lisp-sträng -> funktionsreferens" (case (char sträng 0) (#\m #'skapa-mänsklig-spelare) (#\d #'skapa-ai-spelare) (#\s #'skapa-slump-spelare))) Deklamera vinnaren. (defun presentera-vinnare (vinnarbricka) "bricka ->" (if (eq vinnarbricka 'oavgjort) (format t "Det blev oavgjort!~%") (format t "~a vann. Grattis!~%" (färgnamn-från-bricka vinnarbricka))))... (defun börja-spelar-input (bricktyp) "bricka ->" (sätt-färger-för-bricka bricktyp) (format t "Spelare ~a:~%" (färgnamn-från-bricka bricktyp)) (återställ-färger)) Skriver ut det kosmetiska för en rad. (defun skriv-radhuvud (storlek) "Lisp-heltal ->" (sätt-standardfärger) (dotimes (i storlek) (format t "+---")) (format t "+") (återställ-färger) (terpri)) Skriv ut en bricka. (defun skriv-bricka (bricka) "bricka ->" (skriv-vertikal-kant) (if bricka (progn (sätt-bakgrund (färg-från-bricka bricka)) (sätt-förgrund (färg-från-bricka bricka))) (sätt-standardfärger)) (skriv-tecken (if (ingen-bricka? bricka) " " (if (bricka-svart? bricka) "X" "O"))) (återställ-färger)) (defun skriv-vertikal-kant () "->" (sätt-standardfärger) (princ " ") (återställ-färger)) (defun skriv-tecken (whatever) "Lisp-objekt ->" (format t " ~a " whatever)) Skriv ut en hel spelplan med de möjliga flyttarna integrerad.

allt.cl Page 6 of 17 (defun skriv-spelplan (spelplan möjliga-flyttar) "spelplan x flyttar ->" (setf flytträknare 0) (dotimes (rad (rader spelplan)) (skriv-radhuvud (kolumner spelplan)) (dotimes (kolumn (kolumner spelplan)) (if (flyttar-innehåller? möjliga-flyttar (skapa-flytt (skapa-punkt kolumn rad))) (progn (skriv-vertikal-kant) (sätt-standardfärger) (let ((pos (position-if (lambda (e) (samma-flytt? e (skapa-flytt (skapa-punkt kolumn rad)))) möjliga-flyttar))) (skriv-tecken (char alfabet pos))) (återställ-färger) (setf flytträknare (+ flytträknare 1))) (skriv-bricka (hämta-plats spelplan kolumn rad)) )) (skriv-vertikal-kant) (terpri)) (skriv-radhuvud (kolumner spelplan))) FRÅGOR (defun fråga-efter-sträng (fråga) "Lisp-sträng -> Lisp-sträng" (format t "~a: " fråga) (read-line t)) (defun fråga-efter-nummer (fråga) "Lisp-sträng -> Lisp-heltal" (format t "~a: " fråga) (let ((värde (read t))) (if (numberp värde) värde (progn (format t "Felaktigt tal! Försök igen.~%") (fråga-efter-nummer fråga))))) FÄRG Färg i terminalen enligt ANSI terminal codes-standarden. Ifall använd-färg är satt kommer dessa funktioner köras, annars avbryter de. (defun sätt-bakgrund (färg) "symbol ->" (if (not använd-färg) (return-from sätt-bakgrund)) (format t "~A[~Am" (code-char 27) (cond ((eq färg 'svart) 40) ((eq färg 'röd) 41) ((eq färg 'grön) 42) ((eq färg 'gul) 43) ((eq färg 'blå) 44) ((eq färg 'magenta) 45) ((eq färg 'cyan) 46) ((eq färg 'vit) 47)))) (defun sätt-förgrund (färg) "symbol ->" (if (not använd-färg) (return-from sätt-förgrund)) (format t "~A[~Am" (code-char 27) (cond ((eq färg 'svart) 30)

allt.cl Page 7 of 17 ((eq färg 'röd) 31) ((eq färg 'grön) 32) ((eq färg 'gul) 33) ((eq färg 'blå) 34) ((eq färg 'magenta) 35) ((eq färg 'cyan) 36) ((eq färg 'vit) 37)))) Ställ tillbaka terminalen till standardläget. (defun återställ-färger () "->" (if (not använd-färg) (return-from återställ-färger)) (format t "~A[0m" (code-char 27))) (defun färg-från-bricka (bricka) "bricka -> symbol" (if (bricka-svart? bricka) 'svart 'vit)) (defun färgnamn-från-bricka (bricka) "bricka -> symbol" (if (bricka-svart? bricka) "Svart" "Vit")) (defun textfärg-från-bricka (bricka) "bricka -> symbol" (if (bricka-svart? bricka) 'vit 'svart)) (defun sätt-färger-för-bricka (bricka) "bricka ->" (sätt-bakgrund (färg-från-bricka bricka)) (sätt-förgrund (textfärg-från-bricka bricka))) (defun sätt-standardförgrund () "->" (sätt-förgrund 'svart)) (defun sätt-standardbakgrund () "->" (sätt-bakgrund 'grön)) (defun sätt-standardfärger () "->" (sätt-standardförgrund) (sätt-standardbakgrund)) Grundläggande funktioner för typ- och felhantering. (defun packa-ihop (typ objekt) "abstrakt typ x Lisp-objekt -> abstrakt objekt" (cons typ objekt)) (defun packa-upp (objekt) "abstrakt objekt -> Lisp-objekt" (if (consp objekt) (cdr objekt))) (defun typ (objekt) "abstrakt objekt -> almanackstyp" (if (consp objekt) (car objekt))) (defun typkontroll (värde predikat) (if (not (funcall predikat värde)) (error "~&Värdet ~a är av fel typ, predikat är ~a." värde predikat) t)) Snabbladda alla filer. (defun skapa-mänsklig-spelare (namn bricktyp) "Lisp-sträng x bricka -> spelare" (skapa-spelare #'mänskligt-drag namn bricktyp))

allt.cl Page 8 of 17 Ber skrivbords/terminal-spelaren om ett drag. (defun mänskligt-drag (spelplan spelare möjliga-flyttar) (let ((index (flyttindex-från-beteckning (string-upcase (kör-eventuell-debug (fråga-efter-sträng "Välj ett drag") spelplan)) möjliga-flyttar))) (if (and index (< index (antal-flyttar möjliga-flyttar))) (nth-flytt index möjliga-flyttar) (progn (format t "Felaktig flytt! Försök igen.~%") (mänskligt-drag spelplan spelare möjliga-flyttar))))) Othello Huvudfunktionen Ifall argumentet inte-färg sätts till t kommer den inte rita spelplanen i färger. (defun othello (&optional inte-färg) "sanningsvärde ->" (setf använd-färg (not inte-färg)) (format t "Othello!~%") (presentera-vinnare (spel-loop (skapa-spelarloop (fråga-efter-spelare 2(fråga-efter-nummer "Antal spelare") (skapa-bricka 'vit))) (fråga-efter-spelplan))) (values)) (defun spel-loop (spelarlista spelplan) "spelarlista x spelplan -> spelare" (let* ((spelare (första-spelare spelarlista)) (möjliga (möjliga-flyttar spelplan (bricktyp spelare)))) (skriv-spelplan spelplan möjliga) (format t "~a: ~a - ~a: ~a~%~%" (färgnamn-från-bricka (skapa-bricka 'svart)) (räkna-brickor spelplan (skapa-bricka 'svart)) (färgnamn-från-bricka (skapa-bricka 'vit)) (räkna-brickor spelplan (skapa-bricka 'vit))) (sätt-bakgrund (färg-från-bricka (bricktyp spelare))) (sätt-förgrund (textfärg-från-bricka (bricktyp spelare))) (if (tom-flyttar? möjliga) (progn (format t "~a kan inte lägga och passar!" (spelarnamn spelare)) (återställ-färger) (terpri)) (progn (format t "Det är ~a tur." (spelare-genetiv-namn spelare)) (återställ-färger) (terpri) (gör-flytt spelare spelplan möjliga))) (if (or (har-någon-vunnit? spelplan) (and (tom-flyttar? möjliga) (tom-flyttar? (möjliga-flyttar spelplan (annan-bricka (bricktyp spelare)))))) (vem-leder? spelplan) (spel-loop (resten-spelare spelarlista) spelplan)))) (defun skapa-punkt (x y) "Lisp-heltal x Lisp-heltal -> punkt" (typkontroll x #'numberp) (typkontroll y #'numberp) (packa-ihop 'punkt (list x y))) (defun punkt? (objekt) "Lisp-objekt -> sanningsvã rde" (eq (typ objekt) 'punkt))

allt.cl Page 9 of 17 Funktionerna x och y skall inte användas. (defun x (punkt) (kolumn punkt)) (defun kolumn (punkt) "punkt -> Lisp-heltal" (typkontroll punkt #'punkt?) (first (packa-upp punkt))) (defun y (punkt) (rad punkt)) (defun rad (punkt) "punkt -> Lisp-heltal" (typkontroll punkt #'punkt?) (second (packa-upp punkt))) Testa ifall två punkter är samma. (defun samma-punkt? (punkt1 punkt2) "punkt x punkt -> sanningsvärde" (and (= (kolumn punkt1) (kolumn punkt2)) (= (rad punkt1) (rad punkt2)))) (defun riktning? (objekt) (find objekt (möjliga-riktningar))) (defun möjliga-riktningar () '(över-vänster över över-höger vänster höger under-vänster under under-höger)) Kringfunktioner till typen spelare Validator (defun spelare? (objekt) "Lisp-objekt -> sanningsvärde" (eq 'spelare (typ objekt))) Selector (defun gör-flytt-funktion (spelare) "spelare -> Lisp-funktionsref" (typkontroll spelare #'spelare?) (first (packa-upp spelare))) (defun spelarnamn (spelare) "spelare -> sträng" (typkontroll spelare #'spelare?) (second (packa-upp spelare))) (defun bricktyp (spelare) "spelare -> bricka" (typkontroll spelare #'spelare?) (third (packa-upp spelare))) (defun spelare-genetiv-namn (spelare) "spelare -> Lisp-sträng" (if (or (eq (char (spelarnamn spelare) (- (length (spelarnamn spelare)) 1)) #\S) (eq (char (spelarnamn spelare) (- (length (spelarnamn spelare)) 1)) #\s)) (spelarnamn spelare) (concatenate 'string (spelarnamn spelare) "s"))) Creator (defun skapa-spelare (fref namn bricktyp) "Lisp-funktionsreferens x sträng x bricka -> spelare" (typkontroll fref #'functionp) (typkontroll namn #'stringp) (typkontroll bricktyp #'bricka?) (packa-ihop 'spelare (list fref namn bricktyp))) Hjälpfunktioner Tar en spelare och plockar ut flytt-funktionen och gör sedan

allt.cl Page 10 of 17 en flytt på en spelplan. (defun gör-flytt (spelare plan möjliga) "spelare x spelplan -> spelplan" (lägg-flytt plan (funcall (gör-flytt-funktion spelare) plan spelare möjliga) (bricktyp spelare))) En typ som är till för spelloopen. Kan innehålla ett godtyckligt antal spelare. (defun skapa-spelarlista () "-> spelarlista" (packa-ihop 'spelarlista ())) (defun spelarlista? (objekt) "Lisp-objekt -> sanningsvärde" (eq (typ objekt) 'spelarlista)) (defun lägg-till-spelare (spelarlista spelare) "spelarlista x spelare -> spelarlista" (typkontroll spelarlista 'spelarlista?) (packa-ihop 'spelarlista (append (packa-upp spelarlista) (list spelare)))) (defun första-spelare (spelarlista) "spelarlista -> spelare" (first (packa-upp spelarlista))) (defun resten-spelare (spelarlista) "spelarlista -> spelarlista" (packa-ihop 'spelarlista (rest (packa-upp spelarlista)))) Koppla sista elementet i spelarlistan till det första och få en "oändlig" lista. (defun skapa-spelarloop (spelarlista) "spelarlista -> spelarlista" (packa-ihop 'spelarlista (setf (rest (last (packa-upp spelarlista))) (packa-upp spelarlista)))) Validator (defun spelplan? (objekt) "Lisp-objekt -> sanningsvärde" (eq 'spelplan (typ objekt))) (defun tom-plats? (spelplan kolumn rad) (if (null (hämta-plats spelplan kolumn rad)) t nil)) Selector (defun kolumner (spelplan) "spelplan -> heltal" (first (array-dimensions (matris spelplan)))) (defun rader (spelplan) "spelplan -> heltal" (second (array-dimensions (matris spelplan)))) (defun ändra-plats (spelplan kolumn rad värde) "spelplan x heltal x heltal x bricktyp ->" (setf (aref (matris spelplan) kolumn rad) värde) spelplan) (defun hämta-plats (spelplan kolumn rad) "spelplan x heltal x heltal -> bricka" (aref (matris spelplan) kolumn rad)) (defun hämta-plats-punkt (spelplan punkt) "spelplan x punkt -> bricka" (aref (matris spelplan) (kolumn punkt) (rad punkt)))

allt.cl Page 11 of 17 hämta-plats med rutiner för att kolla att man inte läser utanför spelplanen, i så fall returnerar den symbolen UTANFÖR. (defun säker-hämta-plats (spelplan punkt) "spelplan x punkt -> bricka" (typkontroll punkt #'punkt?) (let ((kolumn (kolumn punkt)) (rad (rad punkt))) (if (or (> (1+ kolumn) (kolumner spelplan)) (> (1+ rad) (rader spelplan)) (< kolumn 0) (< rad 0)) 'utanför (hämta-plats spelplan kolumn rad)))) (defun utanför? (obj) "lisp-objekt -> sanningsvärde" (equal obj 'utanför)) (defun matris (spelplan) "spelplan -> Lisp-array" (packa-upp spelplan)) Creator (defun skapa-spelplan (kolumner rader) "heltal x heltal -> spelplan" (typkontroll kolumner #'numberp) (typkontroll rader #'numberp) (packa-ihop 'spelplan (make-array (list kolumner rader)))) (defun skapa-spelplan-med-brickor (kolumner rader) (let* ((spelplan (skapa-spelplan kolumner rader)) (basx (floor (1- (/ (kolumner spelplan) 2)))) (basy (floor (1- (/ (rader spelplan) 2))))) (ändra-plats spelplan basx basy (skapa-bricka 'svart)) (ändra-plats spelplan (1+ basx) basy (skapa-bricka 'vit)) (ändra-plats spelplan basx (1+ basy) (skapa-bricka 'vit)) (ändra-plats spelplan (1+ basx) (1+ basy) (skapa-bricka 'svart)) spelplan)) Algoritmer (defun kan-inte-bricka-lägga? (spelplan bricka) (tom-flyttar? (möjliga-flyttar spelplan bricka))) (defun är-spelplan-full? (spelplan) "spelplan -> sanningsvärde" (dotimes (y (rader spelplan)) (dotimes (x (kolumner spelplan)) (if (tom-plats? spelplan x y) (return-from är-spelplan-full? nil)))) t) Finns en viss bricka på spelplanen? (defun finns-bricka? (spelplan bricka) "spelplan x bricka -> sanningsvärde" (dotimes (y (rader spelplan)) (dotimes (x (kolumner spelplan)) (let ((pbricka (hämta-plats spelplan x y))) (if (and (not (tom-plats? spelplan x y)) (samma-bricka? bricka pbricka)) (return-from finns-bricka? t))))) nil) Utvärderar om någon har vunnit eller ej. (defun har-någon-vunnit? (spelplan) "spelplan -> sanningsvärde" (if (är-spelplan-full? spelplan) t (not (and

allt.cl Page 12 of 17 (finns-bricka? spelplan (skapa-bricka 'svart)) (finns-bricka? spelplan (skapa-bricka 'vit)))))) (defun räkna-brickor (spelplan bricka) "spelplan x bricka -> lisp-heltal" (let ((tal 0)) (dotimes (y (rader spelplan)) (dotimes (x (kolumner spelplan)) (let ((pbricka (hämta-plats spelplan x y))) (if (and (not (tom-plats? spelplan x y)) (samma-bricka? bricka pbricka)) (setf tal (1+ tal)))))) tal)) Ger tillbaka vilken bricka som leder på en spelplan. (defun vem-leder? (spelplan) "spelplan -> bricka" (let ((vita-brickor (räkna-brickor spelplan (skapa-bricka 'vit))) (svarta-brickor (räkna-brickor spelplan (skapa-bricka 'svart)))) (if (= vita-brickor svarta-brickor) 'oavgjort (if (> vita-brickor svarta-brickor) (skapa-bricka 'vit) (skapa-bricka 'svart))))) (defun punkter-av-bricktyp (spelplan bricktyp) "spelplan x bricka -> lisp-lista av punkt" (let ((punkter (list))) (dotimes (y (rader spelplan)) (dotimes (x (kolumner spelplan)) (let ((pbricka (hämta-plats spelplan x y))) (if (and (not (tom-plats? spelplan x y)) (samma-bricka? pbricka bricktyp)) (setq punkter (cons (skapa-punkt x y) punkter)))))) punkter)) Returnerar en flyttar med motspelare som ligger bredvid punkt som är en bricka. (defun motspelare-bredvid (spelplan bricka punkt) "spelplan x bricka x punkt -> flyttar" (let* ((p-över-vänster (punkt-i-riktning punkt 'över-vänster)) (över-vänster (säker-hämta-plats spelplan p-över-vänster)) (p-över (punkt-i-riktning punkt 'över)) (över (säker-hämta-plats spelplan p-över)) (p-över-höger (punkt-i-riktning punkt 'över-höger)) (över-höger (säker-hämta-plats spelplan p-över-höger)) (p-vänster (punkt-i-riktning punkt 'vänster)) (vänster (säker-hämta-plats spelplan p-vänster)) (p-höger (punkt-i-riktning punkt 'höger)) (höger (säker-hämta-plats spelplan p-höger)) (p-under-vänster (punkt-i-riktning punkt 'under-vänster)) (under-vänster (säker-hämta-plats spelplan p-under-vänster)) (p-under (punkt-i-riktning punkt 'under)) (under (säker-hämta-plats spelplan p-under)) (p-under-höger (punkt-i-riktning punkt 'under-höger)) (under-höger (säker-hämta-plats spelplan p-under-höger))) (lägg-ihop-flyttar (if (and över-vänster (not (utanför? över-vänster)) (not (samma-bricka? bricka över-vänster))) (lägg-till-flytt (skapa-flyttar) (skapa-flytt p-över-vänster)) (skapa-flyttar)) (if (and över (not (utanför? över)) (not (samma-bricka? bricka över))) (lägg-till-flytt (skapa-flyttar) (skapa-flytt p-över)) (skapa-flyttar)) (if (and över-höger (not (utanför? över-höger)) (not (samma-bricka? bricka över-höger))) (lägg-till-flytt (skapa-flyttar) (skapa-flytt p-över-höger)) (skapa-flyttar)) (if (and vänster

allt.cl Page 13 of 17 (not (utanför? vänster)) (not (samma-bricka? bricka vänster))) (lägg-till-flytt (skapa-flyttar) (skapa-flytt p-vänster)) (skapa-flyttar)) (if (and höger (not (utanför? höger)) (not (samma-bricka? bricka höger))) (lägg-till-flytt (skapa-flyttar) (skapa-flytt p-höger)) (skapa-flyttar)) (if (and under-vänster (not (utanför? under-vänster)) (not (samma-bricka? bricka under-vänster))) (lägg-till-flytt (skapa-flyttar) (skapa-flytt p-under-vänster)) (skapa-flyttar)) (if (and under (not (utanför? under)) (not (samma-bricka? bricka under))) (lägg-till-flytt (skapa-flyttar) (skapa-flytt p-under)) (skapa-flyttar)) (if (and under-höger (not (utanför? under-höger)) (not (samma-bricka? bricka under-höger))) (lägg-till-flytt (skapa-flyttar) (skapa-flytt p-under-höger)) (skapa-flyttar))))) Vilken punkt ligger RIKTNING från PUNKT? (defun punkt-i-riktning (punkt riktning) "punkt x riktning -> punkt" (typkontroll punkt #'punkt?) (typkontroll riktning #'riktning?) (let* ((kolumn (kolumn punkt)) (rad (rad punkt)) (över-vänster (skapa-punkt (1- kolumn) (1- rad))) (över (skapa-punkt kolumn (1- rad))) (över-höger (skapa-punkt (1+ kolumn) (1- rad))) (vänster (skapa-punkt (1- kolumn) rad)) (höger (skapa-punkt (1+ kolumn) rad)) (under-vänster (skapa-punkt (1- kolumn) (1+ rad))) (under (skapa-punkt kolumn (1+ rad))) (under-höger (skapa-punkt (1+ kolumn) (1+ rad)))) (case riktning (över-vänster över-vänster) (över över) (över-höger över-höger) (vänster vänster) (höger höger) (under-vänster under-vänster) (under under) (under-höger under-höger)))) Vart får man flytta? Villkor: 1. Måste vara bredvid en bricka av motståndarens färg. Som bredvid gills vertikalt, horisontalt och diagonalt. 2. Om så måste det finnas en bricka av ens egen färg efter motståndarens bricka(or). (defun möjlig-flytt? (spelplan flytt bricktyp) "spelplan x flytt x bricka -> sanningsvärde" (let ((punkt (punkt flytt))) (and (null (hämta-plats-punkt spelplan punkt)) (not (tom-flyttar? (motspelare-bredvid spelplan bricktyp punkt))) (finns-bricka-i-någon-riktning? spelplan bricktyp punkt)))) Punkten är ens egen bricka på planen. Bricktyp är ens egen bricktyp. (defun flyttar-runt-punkt (spelplan punkt bricktyp) "spelplan x punkt x bricka -> flyttar" (finns-tom-i-någon-riktning? spelplan bricktyp punkt)) Leta möjliga flyttar som en viss bricka kan lägga på en spelplan. Använder två algoritmer för att vara så effektiv som möjligt. (defun möjliga-flyttar (spelplan bricktyp)

allt.cl Page 14 of 17 (let* ((vita (räkna-brickor spelplan (skapa-bricka 'vit))) (svarta (räkna-brickor spelplan (skapa-bricka 'svart))) (kvot (/ (+ vita svarta) (* (kolumner spelplan) (rader spelplan))))) (begränsa-flyttar (unika-flyttar (if (> kvot 0.65) (tom-möjliga-flyttar spelplan bricktyp) (början-möjliga-flyttar spelplan bricktyp)))))) En algoritm för att leta möjliga flyttar som är bäst i början, när inte så många brickor lagts ut. (defun början-möjliga-flyttar (spelplan bricktyp) "spelplan x bricka -> flyttar" (setq flyttar (skapa-flyttar)) (let ((punkter (punkter-av-bricktyp spelplan bricktyp))) (dotimes (i (length punkter)) (let ((möjliga-flyttar (flyttar-runt-punkt spelplan (nth i punkter) bricktyp))) (if (not (tom-flyttar? möjliga-flyttar)) (setq flyttar (lägg-ihop-flyttar flyttar möjliga-flyttar)))))) flyttar) En algoritm för att leta möjliga flyttar som är bäst när det finns få tomma rutor. (defun tom-möjlig-flytt? (spelplan flytt bricktyp) "spelplan x flytt x bricka -> sanningsvärde" (let ((punkt (punkt flytt))) (and (null (hämta-plats-punkt spelplan punkt)) (not (tom-flyttar? (motspelare-bredvid spelplan bricktyp punkt))) (finns-bricka-i-någon-riktning? spelplan bricktyp punkt)))) (defun tom-möjliga-flyttar (spelplan bricktyp) "spelplan -> flyttar" (setq flyttar (skapa-flyttar)) (dotimes (rad (rader spelplan)) (dotimes (kolumn (kolumner spelplan)) (let ((flytt (skapa-flytt (skapa-punkt kolumn rad)))) (if (tom-möjlig-flytt? spelplan flytt bricktyp) (setq flyttar (lägg-till-flytt flyttar flytt)))))) flyttar) AI-relaterat (defun kopiera-spelplan (spelplan) "spelplan -> spelplan" (let* ((array (packa-upp spelplan)) (dims (array-dimensions array))) (packa-ihop 'spelplan (adjust-array (make-array dims :displaced-to array) dims)))) Kopiera en spelplan och lägg en flytt på den. (defun kopierad-spelplan-med-flytt (spelplan bricktyp flytt) "spelplan x bricka x flytt -> spelplan" (lägg-flytt (kopiera-spelplan spelplan) flytt bricktyp)) Utläggning Funktionen finns-bricka-i-riktning kollar om det finns en egen bricka i en viss riktning, med minst en annan bricktyp och inget tomrum mellan. (defun finns-bricka-i-riktning-intern (spelplan bricktyp punkt riktning skippa räknare) "spelplan x bricka x punkt x riktningssymbol x sanningsvärde -> punkt eller nil"

allt.cl Page 15 of 17 (let ((bricka (säker-hämta-plats spelplan punkt))) (cond ((and (not skippa) (null bricka)) nil) ((and (utanför? bricka) (not skippa)) nil) ((and (not skippa) (samma-bricka? bricka bricktyp)) (if (> räknare 1) punkt nil)) (t (finns-bricka-i-riktning-intern spelplan bricktyp (punkt-i-riktning punkt riktning) riktning nil (1+ räknare)))))) Finns en viss bricka i en viss riktning? (defun finns-bricka-i-riktning (spelplan bricktyp punkt riktning) (finns-bricka-i-riktning-intern spelplan bricktyp punkt riktning t 0)) (defun finns-bricka-i-någon-riktning-intern (spelplan bricktyp punkt riktningar) (if (endp riktningar) nil (let* ((riktning (first riktningar)) (destpunkt (finns-bricka-i-riktning spelplan bricktyp punkt riktning))) (if destpunkt t (finns-bricka-i-någon-riktning-intern spelplan bricktyp punkt (rest riktningar)))))) (defun finns-bricka-i-någon-riktning? (spelplan bricktyp punkt) (fbinr-intern spelplan bricktyp punkt (möjliga-riktningar))) (defun finns-tom-i-riktning-intern (spelplan bricktyp punkt riktning räknare) "spelplan x bricka x punkt x riktningssymbol x sanningsvärde -> punkt eller nil" (typkontroll spelplan #'spelplan?) (typkontroll bricktyp #'bricka?) (typkontroll punkt #'punkt?) (typkontroll riktning #'riktning?) (let ((bricka (säker-hämta-plats spelplan punkt))) (cond ((utanför? bricka) nil) ((and (> räknare 0) bricka (samma-bricka? bricka bricktyp)) nil) ((and (> räknare 1) (null bricka)) punkt) ((null bricka) nil) (t (finns-tom-i-riktning-intern spelplan bricktyp (punkt-i-riktning punkt riktning) riktning (1+ räknare)))))) Finns det en tom bricka i en viss riktning svarar denna på. (defun finns-tom-i-riktning (spelplan bricktyp punkt riktning) "spelplan x bricka x punkt x riktning -> punkt eller sanningsvärde (nil)" (finns-tom-i-riktning-intern spelplan bricktyp punkt riktning 0)) (defun finns-tom-i-någon-riktning-intern (spelplan bricktyp punkt riktningar) "spelplan x bricka x punkt x lisp-lista av riktning -> sanningsvärde" (if (endp riktningar) (skapa-flyttar) (let* ((riktning (first riktningar)) (destpunkt (finns-tom-i-riktning spelplan bricktyp punkt riktning))) (if destpunkt (lägg-till-flytt (finns-tom-i-någon-riktning-intern spelplan bricktyp punkt (rest riktningar)) (skapa-flytt destpunkt)) (finns-tom-i-någon-riktning-intern spelplan bricktyp punkt (rest riktningar)))))) Bricktypen är ens egen bricktyp och punkten

allt.cl Page 16 of 17 är ens egen punkt. Returnerar flyttar. (defun finns-tom-i-någon-riktning? (spelplan bricktyp punkt) "spelplan x bricka x punkt -> flyttar" (finns-tom-i-någon-riktning-intern spelplan bricktyp punkt (möjliga-riktningar))) Lägg-flytt tar en flytt (punkt) och lägger brickor mellan den och alla andra lämpliga. (defun lägg-flytt-intern (spelplan flytt bricktyp riktningar) "spelplan x flytt x bricka x riktning -> spelplan" (if (endp riktningar) nil (let* ((riktning (first riktningar)) (destpunkt (finns-bricka-i-riktning spelplan bricktyp (punkt flytt) riktning))) (if destpunkt (lägg-mellan spelplan bricktyp (punkt flytt) destpunkt) nil) (lägg-flytt-intern spelplan flytt bricktyp (rest riktningar)))) spelplan) (defun lägg-flytt (spelplan flytt bricktyp) (lägg-flytt-intern spelplan flytt bricktyp (möjliga-riktningar))) ; Funktionen ett-i-rätt-riktning returnerar to-from, fast mellan -1 och 1. (defun ett-i-rätt-riktning (from to) (/ (- to from) (if (= (- to from) 0) 1 (abs (- to from))))) Lägger brickor av färg bricktyp mellan två punkter. (defun lägg-mellan (spelplan bricktyp punkt1 punkt2) (let* ( (k1 (kolumn punkt1)) (k2 (kolumn punkt2)) (r1 (rad punkt1)) (r2 (rad punkt2)) (nästap (skapa-punkt (+ k1 (ett-i-rätt-riktning k1 k2)) (+ r1 (ett-i-rätt-riktning r1 r2))))) (progn (ändra-plats spelplan k1 r1 bricktyp) (if (samma-punkt? punkt1 punkt2) t (lägg-mellan spelplan bricktyp nästap punkt2))))) Fus... eh, debug. (defun byt-brickor (spelplan) (dotimes (kolumn (kolumner spelplan)) (dotimes (rad (rader spelplan)) (let ((bricka (hämta-plats spelplan kolumn rad))) (if bricka (ändra-plats spelplan kolumn rad (annan-bricka (hämta-plats spelplan kolumn rad)))))))) (defun kör-eventuell-debug (sträng spelplan) (if (equal sträng "kazul!") (byt-brickor spelplan)) sträng) Räknar antal kantbrickor resp. hörnbrickor som en bricka har på en spelplan: (defun antal-kantbrickor (spelplan bricktyp) "spelplan x bricka -> lisp-heltal" (let ((antal 0)) (dotimes (kolumn (- (kolumner spelplan) 2)) (if (säker-samma-bricka? bricktyp (hämta-plats spelplan (1+ kolumn) 1)) (setf antal (1+ antal)))

allt.cl Page 17 of 17 (if (säker-samma-bricka? bricktyp (hämta-plats spelplan (1+ kolumn) (1- (rader spelplan)))) (setf antal (1+ antal)))) (dotimes (rad (- (rader spelplan) 2)) (if (säker-samma-bricka? bricktyp (hämta-plats spelplan 1 (1+ rad))) (setf antal (1+ antal))) (if (säker-samma-bricka? bricktyp (hämta-plats spelplan (1- (kolumner spelplan)) (1+ rad))) (setf antal (1+ antal)))) antal)) (defun antal-hörnbrickor (spelplan bricktyp) "spelplan x bricka -> lisp-heltal" (let ((antal 0)) (if (säker-samma-bricka? bricktyp (hämta-plats spelplan 0 0)) (setf antal (1+ antal))) (if (säker-samma-bricka? bricktyp (hämta-plats spelplan 0 (1- (rader spelplan)))) (setf antal (1+ antal))) (if (säker-samma-bricka? bricktyp (hämta-plats spelplan (1- (kolumner spelplan)) 0)) (setf antal (1+ antal))) (if (säker-samma-bricka? bricktyp (hämta-plats spelplan (1- (kolumner spelplan)) (1- (rader spelplan)))) (setf antal (1+ antal))) antal)) # (setf standard '(SPELPLAN. #2A((NIL NIL NIL NIL NIL NIL NIL NIL) (NIL NIL NIL NIL NIL NIL NIL NIL) (NIL NIL NIL NIL NIL NIL NIL NIL) (NIL NIL NIL (BRICKA. SVART) (BRICKA. VIT) NIL NIL NIL) (NIL NIL NIL (BRICKA. VIT) (BRICKA. SVART) NIL NIL NIL) (NIL NIL NIL NIL NIL NIL NIL NIL) (NIL NIL NIL NIL NIL NIL NIL NIL) (NIL NIL NIL NIL NIL NIL NIL NIL)))) (setf vit (skapa-bricka 'vit)) (setf svart (skapa-bricka 'svart)) (setf test1 '(SPELPLAN. #2A((NIL NIL NIL) (NIL (bricka. svart) NIL) (NIL (BRICKA. svart) (BRICKA. vit))))) (setf test2 '(SPELPLAN. #2A((NIL NIL NIL) (NIL (bricka. svart) NIL) (NIL (bricka. vit) (bricka. svart)) (NIL NIL NIL)))) (setf test3 '(SPELPLAN. #2A((NIL NIL NIL NIL NIL) (NIL (bricka. svart) (bricka. vit) NIL NIL) (NIL NIL NIL NIL NIL) (NIL NIL (bricka. svart) NIL NIL) (NIL NIL (bricka. vit) NIL NIL)))) (skriv-spelplan test3 (skapa-flyttar)) # (proclaim '(optimize (speed 3) (safety 1) (space 0) (debug 0)))