Вы находитесь на странице: 1из 19

C-IMPLEMENTATION OF

“TIC-TAC-TOE PROBLEM”
#include <stdio.h>
#include<conio.h>
void main()
{
int i = 0,player = 0,go = 0,row = 0,column = 0,line = 0,winner = 0;
char board[3][3] = {{'1','2','3'},{'4','5','6'},{'7','8','9'}};
clrscr();
for( i = 0; i<9 && winner==0; i++)
{
printf("\n\n");
printf(" %c | %c | %c\n", board[0][0], board[0][1], board[0][2]);
printf("---+---+---\n");
printf(" %c | %c | %c\n", board[1][0], board[1][1], board[1][2]);
printf("---+---+---\n");
printf(" %c | %c | %c\n", board[2][0], board[2][1], board[2][2]);
player = i%2 + 1;
do
{
printf("\nPlayer %d, please enter the number of the square "
"where you want to place your %c: ", player,(player==1)?'X':'O');
scanf("%d", &go);
row = --go/3;
column = go%3;
}while(go<0 || go>9 || board[row][column]>'9');
board[row][column] = (player == 1) ? 'X' : 'O';
if((board[0][0] == board[1][1] && board[0][0] == board[2][2]) ||
(board[0][2] == board[1][1] && board[0][2] == board[2][0]))
winner = player;
else
for(line = 0; line <= 2; line ++)
if((board[line][0] == board[line][1] && board[line][0] == board[line][2])||
(board[0][line] == board[1][line] && board[0][line] == board[2][line]))
winner = player;
}
printf("\n\n");
printf(" %c | %c | %c\n", board[0][0], board[0][1], board[0][2]);
printf("---+---+---\n");
printf(" %c | %c | %c\n", board[1][0], board[1][1], board[1][2]);
printf("---+---+---\n");
printf(" %c | %c | %c\n", board[2][0], board[2][1], board[2][2]);
if(winner == 0)
printf("\n How boring, it is a draw\n");
else
printf("\n Congratulations, player %d, YOU ARE THE WINNER!\n", winner);
getch();
}

OUTPUT :
X|2|3
---+---+---
4|5|6
---+---+---
7|8|9
Player 2, please enter the number of the square where you want to place your O : 4
X|2|3
---+---+---
O|5|6
---+---+---
7|8|9
Player 1, please enter the number of the square where you want to place your X : 5
X|2|3
---+---+---
O|X|6
---+---+---
7|8|9
Player 2, please enter the number of the square where you want to place your O : 6
X|2|3
---+---+---
O|X|O
---+---+---
7|8|9
Player 1, please enter the number of the square where you want to place your X : 9
X|2|3
---+---+---
O|X|O
---+---+---
7|8|X
Congratulations, player 1, YOU ARE THE WINNER!
C-IMPLEMENTATION OF
“WATER-JUG PROBLEM”
#include<stdio.h>
#include<conio.h>
#define MAX 20
void main()
{
int a[MAX][3],b[MAX][3],i,p,temp1,temp2,j,n;
char c;
clrscr();
printf("\n\n x -> 4 litre jug, y -> 3 litre jug.");
printf("\n\n Enter the initial condition of Jugs (x,y) : ");
scanf("%d%d",&a[0][0],&a[0][1]);
a[0][2]=-1;
i=0;
p=1;
while(i!=p)
{
printf("\n\n Are choice for (%d,%d) available (y/n) : ",a[i][0],a[i][1]);
scanf("%c",&c);
while(c=='y')
{
printf("\n Enter the available options for (%d,%d) : ",a[i][0],a[i][1]);
scanf("%d%d",&temp1,&temp2);
for(j=0;(j<p) && !(a[j][0]==temp1 && a[j][1]==temp2);j++);
if(j==p)
{
a[p][0]=temp1;
a[p][1]=temp2;
a[p][2]=i;
p++;
}
c='n';
printf("\n Do you want to enter more choice (y/n) : ");
scanf("%c",&c);
}
i++;
}
printf("\n\n Enter the terminating condition for the problem (x,y) : ");
scanf("%d%d",&temp1,&temp2);
printf("\n\n Solution sequence is :\n");
for(j=0;j<=i;j++)
if(a[j][0]==temp1 && a[j][1]==temp2)
p=j;
j=0;
while(p!=-1)
{
b[j][0]=a[p][0];
b[j][1]=a[p][1];
p=a[p][2];
j++;
}
for(i=(j-1);i>=0;i--)
printf("\n\t\t(%d,%d)",b[i][0],b[i][1]);
getch();
}

OUTPUT :
x -> 4 litre jug, y -> 3 litre jug.
Enter the initial condition of Jugs (x,y) : 0 0
Are choice for (0,0) available (y/n) : y
Enter the available options for (0,0) : 4 0
Do you want to enter more choice (y/n) : y
Enter the available options for (0,0) : 0 3
Do you want to enter more choice (y/n) : n
Are choice for (4,0) available (y/n) : y
Enter the available options for (4,0) : 1 3
Do you want to enter more choice (y/n) : y
Enter the available options for (4,0) : 4 3
Do you want to enter more choice (y/n) : y
Enter the available options for (4,0) : 0 0
Do you want to enter more choice (y/n) : n
Are choice for (0,3) available (y/n) : y
Enter the available options for (0,3) : 3 0
Do you want to enter more choice (y/n) : y
Enter the available options for (0,3) : 4 3
Do you want to enter more choice (y/n) : n
Are choice for (1,3) available (y/n) : y
Enter the available options for (1,3) : 1 0
Do you want to enter more choice (y/n) : y
Enter the available options for (1,3) : 0 3
Do you want to enter more choice (y/n) : n
Are choice for (4,3) available (y/n) : y
Enter the available options for (4,3) : 4 0
Do you want to enter more choice (y/n) : y
Enter the available options for (4,3) : 0 3
Do you want to enter more choice (y/n) : n
Are choice for (3,0) available (y/n) : y
Enter the available options for (3,0) : 3 3
Do you want to enter more choice (y/n) : n
Are choice for (1,0) available (y/n) : y
Enter the available options for (1,0) : 0 1
Do you want to enter more choice (y/n) : n
Are choice for (3,3) available (y/n) : y
Enter the available options for (3,3) : 4 2
Do you want to enter more choice (y/n) : n
Are choice for (0,1) available (y/n) : n
Are choice for (4,2) available (y/n) : y
Enter the available options for (4,2) : 0 2
Do you want to enter more choice (y/n) : n
Are choice for (0,2) available (y/n) : y
Enter the available options for (0,2) : 2 0
Do you want to enter more choice (y/n) : y
Enter the available options for (0,2) : 4 2
Do you want to enter more choice (y/n) : n
Are choice for (2,0) available (y/n) : n
Enter the terminating condition for the problem (x,y) : 2 0
Solution sequence is :
(0,0)
(0,3)
(3,0)
(3,3)
(4,2)
(0,2)
(2,0)
Getting Started in SWI prolog for Windows
Objective : To get oriented with the SWI-interface, learn how to perform basic
tasks of
opening prolog files, querying knowledge databases, and editing prolog files.
1. Install SWI-prolog by going to
http://www.swi-prolog.org/dl-stable.html
Download and run the self-extracting Windows executable.
2. Open SWI-prolog by clicking Start_All Programs_SWI-Prolog_Prolog
You should see the following Command window.

3. Load a sample prolog file likes.pl by


a. Clicking the menu File_Consult
This will open a file-dialog box.
b. Change the directory to
C:\Program Files\pl\demo\
c. Click on likes.pl
A line like the following will appear in the command window.
% c:/Program Files/pl/demo/likes.pl compiled 0.01 sec, 3,908 bytes
likes.pl is a knowledge database that contains knowledge about foods
that sam
likes.
To explore the likes.pl database run the following queries by typing the lines
exactly into
the command prompt (?- ). Remember each clause must end in a . Also,
remember
lower-case words are constants and words that begin with capital letters are
variables, so
be careful!
likes(sam,spaghetti).
indian(curry).
italian(spaghetti).
italian(curry).

Q1. Answer the following questions by constructing appropriate queries of


the
knowledge database. Along with your answer, write down the query you
used to answer
each question.
a. Does sam like tandoori?
b. Does sam like lasagna?
c. Is curry mild?
d. Is dahl chinese food or indian food or italian food?
e. Is sam italian?

Q2. Run the following query, by typing it exactly into the prompt:
chinese(X).
Press ENTER after the result appears.
Run the query again, by typing it exactly into the prompt:
chinese(X).
But press semi-colon repeatedly.
In your own words, when running a query how does pressing ; differ
from
pressing ENTER?

Q3. Answer the following questions by constructing appropriate queries of


the
knowledge database. Along with your answer, write down the query(ies) you
used to
answer each question.
a. What are the types of indian foods in the database?
b. Which ethnic food (indian, italian, or chinese) has the most foods
in
the database?
c. What foods does sam like?
4. Open the likes.pl file for editing by
a. Clicking File_Edit
This will open a file dialog box.
b. Click on likes.pl.
This opens an editor (Notepad) with the likes.pl database:
Alternatively you can type the following query to open the editor.
edit(likes).
a. Find the block of code with the list of Italian foods:
italian(pizza).
italian(spaghetti).
b. add a new kind of Italian food by typing.
italian(lasagna).
c. Save your file and exit.
Q4a. Now does sam like lasagna?
- Run the query likes(sam, lasagna). to find out.
b. In your own words, what possible conclusions can be drawn when
prolog returns
no for a query?
c. Open the likes.pl file for editing again. Write down the rule(s) in likes.pl
that you
think prolog used to determine whether or not sam likes lasagna.
Q5. Add a new type of indian food to the knowledge database.
indian(naan).
You must save the file and exit the editor before you can query the
database.
Does sam like naan? Why or why not? Hint: open the likes.pl file to
explore
the database’s rules.

Q6. Add a new ethnic food category of your choosing (e.g. mexican) to the
knowledge
database likes.pl with at least 3 food types (e.g. nachos) by adding
simple clauses
of the form mexican(nachos). to likes.pl. Construct a rule (in likes.pl) to
determine when sam likes that ethnic food. Perform a query to see if
sam
likes your ethnic food. Write down your changes to likes.pl (both
assertions and
your rule) along with your query(ies) and its results.

Q7. For those of you who would like some additional PROLOG programming
challenges, here are two more problems you can cut your teeth on:
A. Suppose we are given a knowledge base with the following facts:
tran(eins,one).
tran(zwei,two).
tran(drei,three).
tran(vier,four).
tran(fuenf,five).
tran(sechs,six).
tran(sieben,seven).
tran(acht,eight).
tran(neun,nine).
Write a predicate listtran(G,E) which translates a list of German number
words to
the corresponding list of English number words. For example:
listtran([eins,neun,zwei],X).
should give:
X = [one,nine,two].
Your program should also work in the other direction. For example, if you
give it the
query
listtran(X,[one,seven,six,two]).
it should return:
X = [eins,sieben,sechs,zwei].
Hint: to answer this question, first ask yourself `How do I translate the empty
list of
number words?'. That's the base case. For non-empty lists, first translate the
head of the list, then use recursion to translate the tail.

B. Consider the following set of six English words:


abalone, abandon, anagram, connect, elegant, enhance.
They are to be arranged in a crossword puzzle like fashion in the grid
given below.
The following knowledge base represents a lexicon containing these
words.
word(abalone,a,b,a,l,o,n,e).
word(abandon,a,b,a,n,d,o,n).
word(enhance,e,n,h,a,n,c,e).
word(anagram,a,n,a,g,r,a,m).
word(connect,c,o,n,n,e,c,t).
word(elegant,e,l,e,g,a,n,t).
Your task is to write a predicate crosswd/6 that tells us how to fill the grid,
i.e. the
first three arguments should be the vertical words from left to right and the
following
three arguments the horizontal words from top to bottom.

KNOWLEDGE BASE
File likes.pl
likes(sam,Food) :-
indian(Food),
mild(Food).
likes(sam,Food) :-
chinese(Food).
likes(sam,Food) :-
italian(Food).
likes(sam,chips).

indian(curry).
indian(dahl).
indian(tandoori).
indian(kurma).

mild(dahl).
mild(tandoori).
mild(kurma).

chinese(chow_mein).
chinese(chop_suey).
chinese(sweet_and_sour).

italian(pizza).
italian(spaghetti).

QUERIES :
Q.1
likes(sam,tandoori).
Yes
a)  Sam likes tandoori.

likes(sam,lasagna).
No
b)  Sam doesn’t like lasagna.

?- chinese(X).
X = chow_mein ;
X = chop_suey ;
X = sweet_and_sour ;
No
?- indian(X).
X = curry ;
X = dahl ;
Yes
c)  Dahl is an Indian food.
d) 
Q.2
?- chinese(X).
X = chow_mein
Yes
?- chinese(X).
X = chow_mein ;
X = chop_suey ;
X = sweet_and_sour ;
No

When ENTER is pressed the query terminates after showing only single result. The ‘Yes’ word shows that
other result also exists. While, When semi-colon is pressed, the query terminates after showing all the
results. The ‘No’ word show that no more result exist for this query.
Q.3
?- indian(X).
X = curry ;
X = dahl ;
X = tandoori ;
X = kurma ;
No
a)  Available Indian foods are : curry, dahl, tandoori, kurma.

italian(X).
X = pizza ;
X = spaghetti ;
No

?- chinese(X).
X = chow_mein ;
X = chop_suey ;
X = sweet_and_sour ;
No
b)  Thus Indian food has most foods in the database.

?- likes(sam,X).
X = dahl ;
X = tandoori ;
X = kurma ;
X = chow_mein ;
X = chop_suey ;
X = sweet_and_sour ;
X = pizza ;
X = spaghetti ;
X = chips ;
c)  Sam likes curry, dahl, tandoori, kurma, pizza, spaghetti, chow_mein, chop_suey,
sweet_and_sour
foods.
Q.4
likes(sam,tandoori).
Yes
a)  Sam likes lasagna.
b)  When Prolog returns ‘No’ for a query, it means that the record doesn’t exists in the
database.
c) 
likes(sam,Food) :- italian(Food).
italian(lasagna).
Q.5
likes(sam,naan).
No
 Sam doesn’t like naan because Sam likes only mild Indian foods & naan is not a mild food.
Water Jug Solution

Lisp code to for goalp and new-states


;;; Solve the Water Jug problem
(in-package "USER")

(defvar *start* '(0 0))

(defun first-jug (state) (car state))


(defun second-jug (state) (cadr state))
(defun mk-state (f s) (list f s))

(defun goalp (state)


(eq (first-jug state) 2))

(defun new-states (state)


(remove-null
(list
(fill-first state)
(fill-second state)
(pour-first-second state)
(pour-second-first state)
(empty-first state)
(empty-second state))))

(defun remove-null (x)


(cond
((null x) nil)
((null (car x)) (remove-null (cdr x)))
((cons (car x) (remove-null (cdr x))))))

(defun fill-first (state)


(cond
((< (first-jug state) 4) (mk-state 4 (second-jug state))))))

(defun fill-second (state)


(cond
((< (second-jug state) 3) (mk-state (first-jug state) 3))))

(defun pour-first-second (state)


(let ( (f (first-jug state))
(s (second-jug state)))
(cond
((zerop f) nil) ; Cant pour nothing
((= s 3) nil) ; Second full
((<= (+ f s) 3) ; Empty first into second
(mk-state 0 (+ f s)))
(t ; Fill second from first
(mk-state (- (+ f s) 3) 3)))))

(defun pour-second-first (state)


(let ( (f (first-jug state))
(s (second-jug state)))
(cond
((zerop s) nil) ; Cant pour nothing
((= f 4) nil) ; First full
((<= (+ f s) 4) ; Empty second into first
(mk-state (+ f s) 0))
(t ; Fill first from second
(mk-state 4 (- (+ f s) 4))))))

(defun empty-first (state)


(cond
((> (first-jug state) 0) (mk-state 0 (second-jug state)))))

(defun empty-second (state)


(cond
((> (second-jug state) 0) (mk-state (first-jug state) 0))))

Code for Depth First Search


;;; Depth first search with state limit
(in-package "USER")

(defun dfs (state depth limit)


(setf *nodes* 0)
(setf *expanded* 0)
(setf *branches* 0)
(setf *limit* limit)
(setf *result* (dfs1 state depth))
(print (list *nodes* *expanded* *branches*))
*result*
)

;;; dfs1 expands a node and calls dfs2 to recurse on it

(defun dfs1 (state depth)


(setf *nodes* (+ 1 *nodes*))
(cond
((goalp state) (list state))
((zerop depth) nil)
((> *nodes* *limit*) nil)
((let ((children (new-states state)))
(setf *expanded* (+ 1 *expanded*))
(setf *branches* (+ (length children) *branches*))
(let ((result (dfs2 children (- depth 1))))
(and result (cons state result)))))))

;;; dfs2 recurses on each sibling from a single node, calling dfs1
(defun dfs2 (states depth)
(cond
((null states) nil)
((dfs1 (car states) depth))
((dfs2 (cdr states) depth))))

Code for Breadth First Search


;;; Solve by breadth-first search
(in-package "USER")

(defun bfs (state limit)


(setf *nodes* 0)
(setf *expanded* 0)
(setf *branches* 0)
(setf *limit* limit)
(setf *result* (bfs1 (list (list state))))
(print (list *nodes* *expanded* *branches*))
(reverse *result*))

(defun bfs1 (queue)


(setf *nodes* (+ 1 *nodes*))
(cond
((null queue) nil)
((goalp (caar queue)) (car queue))
((> *nodes* *limit*) nil)
((let ((children (new-states (caar queue))))
(setf *expanded* (+ 1 *expanded*))
(setf *branches* (+ (length children) *branches*))
(bfs1
(append
(cdr queue)
(mapcar
#'(lambda (state)
(cons state (car queue)))
children)))))))

Sample Run
;;; Sun Common Lisp, Development Environment 4.0.0 , 6 July 1990
;;; Sun-4 Version for SunOS 4.0.x and sunOS 4.1

> (compile-file "wj.lisp")


#P"/usr2/mlm/wj.sbin"

> (compile-file "bfs")


#P"/usr2/mlm/bfs.sbin"

> (compile-file "dfs")


#P"/usr2/mlm/dfs.sbin"

> (load "wj")


> (load "dfs")
> (load "bfs")

> *start*
(0 0)

> (new-states *start*)


((4 0) (0 3))

> (dfs *start* 7 100000)


(584 206 591) ; Branching factor 2.86 (591/206)
((0 0) (4 0) (1 3) (1 0) (0 1) (4 1) (2 3))

> (bfs *start* 100000)


(341 340 981) ; Branching factor 2.88 (981/340)
((0 0) (4 0) (1 3) (1 0) (0 1) (4 1) (2 3))
8 – Bit puzzle Using BEST FIRST SEARCH
Objective: Write a prolog program to use the BEST FIRST SEARCH applied to the 8-puzzle
problem.

Theory

The 8-puzzle is a square tray in which are placed eight square tiles. The remaining ninth square
is uncovered. Each tile has a number on it. A tile that is adjacent to the blank space can be slid
into that space. A game consists of a starting position and a specified goal position. The goal is to
transform the starting position into the goal position by sliding the tiles around.

2 8 3

1 6 4
1 2 3
7 5
8 4

7 6 5

Program Code

% s(Node, SuccessorNode, Cost)

s( [Empty | Tiles], [Tile | Tiles1], 1) :- % All arc costs are 1


swap( Empty Tile, Tiles Tiles1 ). % Swap Empty and Tile in Tiles

swap( Empty, Tile, [Tile | Ts], [Empty | Ts] ) :-


mandist( Empty , Tile, 1).
swap ( Empty, Tile, [T1 | Ts], [T1 | Ts1] ) :-
swap( Empty, Tile, Ts, Ts1).

mandist( X/Y, X1/Y1, D) :-


dif(Y, Y1, Dy),
D is Dx + Dy.

dif( A, B, D) :-
D is A-B, D >=0, !;
D is B-A.
h( [Empty | Tiles}, H) :-
goal( [Empty1 | GoalSquares] ),
totdist( Tiles, GoalSquares, D),
seq( Tiles S),
H is D + 3*S.

totdist( [] [], 0).

totdist( [Tile | Tiles], [Square | Squares] D) :-


mandist( Tile, Square, D1),
totdist( Tiles, Squares, D2),
D is D1 + D2.

% seq( TilePositions, Score): sequence score

seq( [First | OtherTiles], S) :-


seq( [First | OtherTiles],First, S).

seq( [Tile1, Tile2 | Tiles], First, S) :-


score( Tile1, Tile2 S1),
seq( [ Tile2 | Tiles], First, S2),
S is S1 + S2.

seq( [Last], First, S) :-


score( last First, S).
score( 2/2, _ 1) :- !. % Tile in centre scores 1

score( 1/3, 2/3, 0) :- !.


score( 2/3, 3/3, 0) :- !.
score( 3/3, 3/2, 0) :- !.
score( 3/2, 3/1, 0) :- !.
score( 3/1, 2/1, 0) :- !.
score( 2/1, 1/1, 0) :- !.
score( 1/1, 1/2, 0) :- !.
score( 1/2, 1/3, 0) :- !.
score(_,_,2) % Tiles out of sequence score 2

goal( [2/21/32/3.3/3,3/23/1,2/1,1/1,1/2]). % Goal squares for tiles

% Display a solution path as a list of board positions

showsol( [] )

showsol( [P | L] ) :-
showsol( L ),
nl, write( ‘---‘)
showpos( P).

% Display a board position

showpos( [S0,S1,S2,S3,S4,S5,S6,S7,S8] ) :-
member( Y, [3,2,1] ), % Order of Y-coordinates
nl, member( X, [1,23] ) % Order of X-coordinates
member( Tile-X/Y, ‘’-S0,1-S1,2-S2,3-S3,4-S4,5-S5,6-S6,7-S7,8-S8] ),
% Tile on square X/Y
write( Tile),
fail %Backtrack to next square ;
true. % All squares done

% Starting positions for some puzzles

start1( [2/2,1/3,3/2,2/3,3/3,3/1,2/1,1/1,1/2] ).
start2( [2/1,1/2,1/3,3/3,3/2,3/1,2/2,1/1,2/3] ).
start3( [2/2,2/3,1/3,3/1,1/2,2/1,3/31/1,3/2] ).
?- start1( Pos), bestfirst( Pos, Sol), showsol( Sol).