Skip to content

Instantly share code, notes, and snippets.

@ayeks
Last active December 16, 2015 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ayeks/efc60f808673386e4b47 to your computer and use it in GitHub Desktop.
Save ayeks/efc60f808673386e4b47 to your computer and use it in GitHub Desktop.
Tictactoe implementation for the Prolog Course. German lecturer, german comments, sorry.Developed with SWI Prolog.
% Copyright (C) 2013 Lars Richter
%
% 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 3 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, see <http://www.gnu.org/licenses/>
% Feldvariablen werden zur Laufzeit hinzugefügt
% x ist Computer, o ist Nutzer
:- dynamic x/1.
:- dynamic o/1.
% Einleitungstext
:-nl,nl,
write(' ***********************************************************'),nl,
write(' * Willkommen beim 3 Gewinnt Spiel, oder auch TicTacToe. *'),nl,
write(' * Ein Spiel starten sie durch den Befehl "start." *'),nl,
write(' * Alle Eingaben müssen einen Punkt am Ende stehen haben! *'),nl,
write(' * Gespeicherte Werte löschen sie mit: "löschen." *'),nl,
write(' * Ein neues Spiel wird durch "neu." gestartet. *'),nl,
write(' * Viel Spaß wünscht Lars. *'),nl,
write(' ***********************************************************'),nl,nl.
% End Linien die Zielstrategien vorgeben
endLinie(1,2,3).
endLinie(4,5,6). %endLinie(4,5,6). %endLinie(6,5,4).
endLinie(7,8,9).
endLinie(1,4,7).
endLinie(2,5,8).
endLinie(3,6,9).
endLinie(1,5,9).
endLinie(3,5,7).
% Vergleich der aktuellen Linie mit Permutationen der Endlinien
linie(A,B,C):-endLinie(A,B,C).
linie(A,B,C):-endLinie(B,C,A).
linie(A,B,C):-endLinie(C,A,B).
linie(A,B,C):-endLinie(A,C,B).
linie(A,B,C):-endLinie(C,B,A).
linie(A,B,C):-endLinie(B,A,C).
% Funktion um Feld auszuwählen welches vom Computer gewählt wird
% Feld muss sinnvoll UND frei sein
setze(Feld):-sinnvoll(Feld),frei(Feld).
% ein freies Feld ist noch nicht im Datenbestand angelegt
% x ist Computer, o ist Nutzer
frei(Feld):-not(x(Feld)),not(o(Feld)).
% Suche eines sinnvolles Feldes
% gewichtet nach Siegwahrscheinlichkeit
sinnvoll(Feld):- sieg(Feld). % Feld welches den Sieg bedeutet
sinnvoll(Feld):- verhindertNied(Feld). % Feld welches Niederlage verhindert
sinnvoll(Feld):- führtZumSieg(Feld). % Feld welches zum Sieg führt
sinnvoll(Feld):- cpuSetzt(Feld). % Erstwert wählen
% wenn schon 2 "x" Parameter vorhanden sind ergibt sich Feld
% aus dem letzten Parameter gesamten endLinie
sieg(Feld):- x(A), x(B), linie(A,B,Feld).
% wenn 2 "o" Parameter gegeben sind und diese auf einer Endlinie liegen
% ist Feld der fehlende Parameter zu den beiden
verhindertNied(Feld):- o(A), o(B), linie(A,B,Feld).
% wenn 1 "x" Parameter gegeben ist dann liegt Feld auf einer endLinie zu
% diesem Parameter
führtZumSieg(Feld):- x(A), linie(A,Feld,_).
% wenn noch keine "x" Werte exisistieren wird ein Startwert genommen
cpuSetzt(5). % optimal ist die Mitte des Spielfeldes
cpuSetzt(7). % falls die Mitte schon belegt ist eine Ecke
% wenn 5 belegt würde frei(Feld) false werden
% ein Spiel ist unentschieden wenn kein Feld mehr frei ist
spielUnent:-not(frei(1)),not(frei(2)),not(frei(3)),
not(frei(4)),not(frei(5)),not(frei(6)),
not(frei(7)),not(frei(8)),not(frei(9)).
% Ausgabe falls ein Spielfeld voll ist.
spielVoll:-spielUnent,write('Es ist ein unentschieden! "neu." für ein neues Spiel. ').
% Spielende Bedinungen
% Computer hat eine Linie aufgebaut
spielGewonnen:-x(A), x(B), x(C), linie(A,B,C), write('Computer hat gewonnen! "neu. für ein neues Spiel.').
% Spieler hat eine Linie aufgebaut
spielGewonnen:-x(A), x(B), x(C), linie(A,B,C), write('Spieler hat gewonnen! "neu. für ein neues Spiel.').
%Das Spielfeld ist voll
spielGewonnen:-spielVoll.
%%%%%%%%% Darstellung des aktuellen Spielfeldes %%%%%%%%%%%%%%
% Abfragen ob Feld durch x / o belegt ist und entsprechende Ausgabe
anzeigeFeld(Feld):-x(Feld),write('|x'). % x gefunden
anzeigeFeld(Feld):-o(Feld),write('|o'). % o gefunden
anzeigeFeld(Feld):-not(x(Feld)),not(o(Feld)),write('|_'). % weder x noch o
% Vorlage ausgeben
anzVorl1:-write(' |1|2|3|').
anzVorl2:-write(' |4|5|6|').
anzVorl3:-write(' |7|8|9|').
le:-write('|'). % Endlinie
% Aktuelles Spielfeld ausgeben
anzeigen:-anzeigeFeld(1),anzeigeFeld(2),anzeigeFeld(3),le,anzVorl1,nl,
anzeigeFeld(4),anzeigeFeld(5),anzeigeFeld(6),le,anzVorl2,nl,
anzeigeFeld(7),anzeigeFeld(8),anzeigeFeld(9),le,anzVorl3,nl,nl.
%%%%%%%%% Benutzerinteraktionen %%%%%%%%%%%%%%
% Aufforderung für Benutzer eine Eingabe zu tätigen
benutzerZug:- write('Machen sie ihren Zug auf Feld 1-9: '),
read(BZug), % Lesen der Eingabe
zugMöglich(BZug), % Prüfung ob Eingabe Korrekt
assert(o(BZug)). % Neues Element mit Eingabeposition anlegen
benutzerZug:-benutzerZug. % Falls Eingabe nicht korrekt, Wiederholung
% Prüfung ob Benutzereingabe korrekt ist
zugMöglich(X):- X > 0, % Eingabe liegt im Bereich 1 bis 9
X < 10,
integer(X), % Eingabe ist eine ganze Zahl
frei(X). % Eingegebenes Feld ist frei
% Automatischer Spielzug des Computers
computerZug:-setze(CZug), % Auswahl eines geeigneten Feldes
write('Computer hat auf Feld '), write(CZug), write(' gesetzt:'),nl,
assert(x(CZug)). % Neues Element anlegen
% Gespeicherte Feldpositionen löschen
löschen :- x(A), retract(x(A)), fail. % solange x(A) ex. lösche diese
löschen :- o(A), retract(o(A)), fail. % solange o(A) ex. lösche diese
löschen :- write('Felder gelöscht'),nl. % Ausgabe das löschen erfolgt ist
% Spielablaufschleife
% Prüfung ob Ende, Eingabe, Anzeige, Prüfung ob voll, Computer, Anzeige
start:- spielGewonnen,!. % um schleife gänzlich zu verlassen
start:- benutzerZug,nl,anzeigen,!, % da sonst Schleife in benutzerZug wenn Spielfeld voll ist
not(spielVoll), % Prüfung ob Spielfeld noch nicht voll ist
computerZug,nl,anzeigen,!, % da sonst wiederholung computerZug, anzeigen bis voll
start.
% Start eines neuen Spiels mit vorherigem löschen
% der gespeicherten Werte
neu:- löschen, start.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment