Last active
December 16, 2015 15:09
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% 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