8puzzle codigo
TRANSCRIPT
-
7/27/2019 8puzzle codigo
1/21
8puzzle.h
#define UP 0#define DOWN 1#define RIGHT 2#define LEFT 3
#define NUM_OPERATORS 4
typedef struct tState_ {int cells[3][3];int r,c;
} tState
8puzzle.c
#include #include "8puzzle.h"#include "search.h"
static int initcells[3][3] ={{1,2,3},{4,5,6},{7,8,0}
};
static int goalcells[3][3] ={{4,1,3},{7,2,5},
{0,8,6}};
/*static int goalcells[3][3] ={{1,2,3},{4,0,6},{7,5,8}
};*/
tState *initialState() {tState *s = (tState *)malloc(sizeof(tState));int i,j;for (i=0;ir=2; s->c=2;return s;
}
int goalTest(tState *s) {
-
7/27/2019 8puzzle codigo
2/21
int i,j;
for (i=0;ir>0;case DOWN: return s->rc>0;case RIGHT: return s->cr--; break;case DOWN: result->r++; break;case LEFT: result->c--; break;case RIGHT: result->c++; break;
}result->cells[result->r][result->c]=0;result->cells[old->r][old->c]=old->cells[result->r][result->c];
return result;}
int cost(unsigned op,tState *s) {return 1;
}
int stateEqual(tState *s1,tState *s2) {return (memcmp(s1,s2,sizeof(tState))==0);
}
/*--- DISPLAY FUNCTIONS -----------------------------------------------*/
void showState(tState *s) {int i,j;
for (i=0; i
-
7/27/2019 8puzzle codigo
3/21
case DOWN: printf("DOWN");break;case LEFT: printf("LEFT");break;case RIGHT: printf("RIGHT");break;
}}
////////////queue.h
/****************************************************************************** QUEUE.h* Pedro Cabalar 15/10/2004
** A QUEUE is a single connected round list. The QUEUE itself is apointer* used to point at any moment the last element in the list.
*****************************************************************************/
struct qNode {struct qNode *next;int data[0];
};
typedef struct qNode *QUEUE;
/* qEMPTY: returns the empty queue (represented as the NULL pointer) */#define qEMPTY NULL
/* qIsEmpty(QUEUE q);* Decides whether QUEUE q is empty or not. It is equivalent to* the expression q==qEMPTY*/#define qIsEmpty(q) ((q)==NULL)
/* qIsNotEmpty(QUEUE q);* The opposite to qIsEMPTY. It is equivalent to the expression q!=qEMPTY*/
#define qIsNotEmpty(q) ((q)!=NULL)
/* qFirst(QUEUE q,type);* Returns a pointer to the data of the first element in the list,assuming* that the element type is 'type'.* EXAMPLE:* printf("%d\n",*qFirst(q,int));* will print the first element of q, assuming it is an integer number.* REQUIRES: q must be non-empty.
-
7/27/2019 8puzzle codigo
4/21
*/#define qFirst(q,type) ((type *)(q)->next->data)
/* qNext(QUEUE q,type);* Returns a QUEUE pointer to the next element from q.* Remember that the end of the list is not a NULL pointer, but isconnected
* instead to the first element (it is a round list).* REQUIRES: q must be non-empty.*/#define qNext(q) ((q)->next)
/* qInsertAt(QUEUE *pq,QUEUE pos,void *e,unsigned int size);* Inserts an element of size 'size' whose address is pointer 'e' at the* position pointed by QUEUE pointer 'pos'.* REQUIRES: 'pos' must be one of the pointers inside the queue *pq.* MODIFIES: the queue elements and (possibly) the queue pointer *pq.*/#define qInsertAt(pq,pos,e,size)((*pq)==(pos))?qInsertFirst(pq,e,size):qInsertFirst(&p,e,size)
/* qPUSH(QUEUE *pq,void *e,type)* Pushes element of type 'type' whose address is pointer 'e' at the* top of the queue pointed by 'pq'. Note that 'pq' must be of type(QUEUE *),* since the queue pointer can be modified.* MODIFIES: the queue elements and (possibly) the queue pointer *pq.*/#define qPUSH(pq,e,type) qInsertFirst(pq,(void *)e,sizeof(type))
/* qPOP(QUEUE *pq,void *e,type)* Retrieves and deletes the top element of queue *pq, storing it ataddress* 'e', assuming that its type is 'type'.
* REQUIRES: the queue *pq must be non-empty.* MODIFIES: the content of the area pointed by 'e', the queue elements,and* (possibly) the queue pointer *pq.*/#define qPOP(pq,e,type) {memcpy((void *)e,(*(pq))->next->data,sizeof(type)); qDeleteFirst(pq);}
/* See qOrderedInsert */#define REPEATING 1
int qInsertFirst(QUEUE *pq, void *e, int size);/* Inserts an element of size 'size' pointed by 'e' as the first element
of* queue *pq.* MODIFIES: the queue elements and (possibly) the queue pointer *pq.*/
int qInsertLast(QUEUE *pq, void *e, int size);/* Inserts an element of size 'size' pointed by 'e' as the last elementof* queue *pq.* MODIFIES: the queue elements and (possibly) the queue pointer *pq.
-
7/27/2019 8puzzle codigo
5/21
*/
int qDeleteFirst(QUEUE *pq);/* Deletes the first element of queue *pq* MODIFIES: the queue elements and the queue pointer *pq.*/
QUEUE qBrowse(QUEUE q, int (*found)(QUEUE , void *),void *data);/* Allows browsing the queue q and performing some arbitrary operationuntil* the end of the queue is reached or some element is found.* Argument 'found' is a pointer to a function of type* int (*found) (QUEUE pos,void *data)* that will be called for each pointer 'pos' to each element in list'q'.* When this function returns 0, the browsing will continue untilreaching* the queue end. Otherwise, it may return 1 (for instance, when somesearched* element is found) and the browsing will stop at that moment.
* The pointer 'data' is used to pass common data to each call offunction* (*found).* REQUIRES: function (*found) should return 0 or 1 and should not modify* the element pointers (should not delete or insert elements in q).* MODIFIES: It depends on function (*found), which can modify thecontent of* the elements in the queue.* EXAMPLE: We want to add some constant k to all the elements in a listof* integer numbers until we reach some negative number:** int addConstant(QUEUE q,void *data) {* if (*qFirst(q,int) < 0)
* return 1;* int *pk=(int *)data;* *qFirst(q,int) += *pk;* return 0;* }** ...* int k=10;* qBrowse(q,addConstant,&k);* ...*/
int qDelete(QUEUE *pq, QUEUE pos);
/* Deletes the element of queue *pq at position pointed by queue pointer'pos'.* REQUIRES: 'pos' must be one of the valid position pointers insidequeue* *pq.* MODIFIES: the queue elements and possibly the content of *pq.*/
int qMove(QUEUE *q1, QUEUE *q2, int (*movethis)(void *),int size);/* Moves all the elements in *q1 to *q2 that satisfy a property specified
-
7/27/2019 8puzzle codigo
6/21
* by the generic function (*movethis). The moved elements are removedfrom* *q1 and appended to *q2, that is, they are inserted in the end. Theelements* size is fixed to 'size'.* MODIFIES: the elements of both queues, and possibly *q1 and *q2.*/
int qFree(QUEUE *q);/* Deletes all the queue elements leaving *q empty. */
int qOrderedInsert(QUEUE *q, void *e, int size,int (*cmp)(void *, void*),
char repeating);/* Makes an ordered insertion of element of size 'size' pointed by 'e' in* queue *q. Generic function (*cmp) is used to compare two elements* (passed as void pointers) so that it returns a value 0 if the first element isgreater.* Argument 'repeating' is used to point out whether we allow repeated
elements* or not (1 means with repeated elements, 0 means no repeated elements).* REQUIRES: the elements in *q should be ordered with respect to (*cmp)* ordering criterion.* MODIFIES: the queue elements and (possibly) the pointer *q.*/
int qDeleteThoseThat(QUEUE *q,int (*DeleteThis)(QUEUE pos,void*data),void *data);/* Deletes from queue *q all those elements that satisfy proertyspecified* by generic function (*DeleteThis). Argument 'data' is used for passing* additional data to (*DeleteThis) if needed.* REQUIRES: function DeleteThis should return 1 if the first element of
* pointer 'pos' should be deleted, and 0 otherwise.* MODIFIES: the queue elements and (possibly) the pointer *q.*/
QUEUE qCopy(QUEUE q,int size);/* Returns a full copy of q. */
QUEUE qMerge(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *),charrepeating);/* It returns a list containing the result of merging the two orderedlists q* and r. The new list contains a copy of the elements in the old lists.* The ordering criterion is specified by the generic function (*cmp)
(see* qOrderedInsert). When 'repeating' is 0, repeated elements are copiedonly* once. The size elements is fixed to 'size'.*/
QUEUE qIntersect(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *));/* Returns the common elements of queues q and r. The new list contains a* copy of the elements in the old lists. Generic function (*cmp) returns0
-
7/27/2019 8puzzle codigo
7/21
* when two elements are equal (see qOrderedInsert). The size elements is* fixed to 'size'.*/
QUEUE qDiff(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *));/* Returns the elements in q not in r. The new list contains a* copy of the elements in the old lists. Generic function (*cmp) returns
0* when two elements are equal (see qOrderedInsert). The size elements is* fixed to 'size'.*/
unsigned int qCount(QUEUE q);/* Returns the number of elements in a list. */
void *Queue2Array(QUEUE q,unsigned int size,unsigned int *num);/* Returns an array (void *) containing a copy of all the elements in the* queue q. The elements size is fixed to 'size'.* It also returns the number of elements in *num.*/
QUEUE qCat(QUEUE q,QUEUE r);/* Returns the result of appending queue r in the end of queue q.* The new list contains a copy of the elements in the old lists.*/
////////////////queue.c
#include #include #include #include "queue.h"
#define BREAKLINK(Q,QOLD,QNEXTOLD) {(QOLD)=(Q); (QNEXTOLD)=(Q)->next;(Q)=(Q)->next; (QOLD)->next=qEMPTY;}
/* Round queues */
static QUEUE qAux;
int qInsertFirst(QUEUE *q, void *e, int size){QUEUE p;
if ((p=(QUEUE)malloc(sizeof(struct qNode)+size))!=NULL){memcpy((void *)(p->data),e,size);
if (qIsEmpty(*q))
-
7/27/2019 8puzzle codigo
8/21
{ *q=p;(*q)->next=(*q);
}else{ p->next = (*q)->next;
(*q)->next = p;}
return 1;}else return 0;
}
int qDeleteFirst(QUEUE *q){QUEUE p;
if (qIsEmpty(*q)) return 0;
if (*q == (*q)->next)
{ free(*q);*q=qEMPTY;
}else{ p=(*q)->next;(*q)->next=p->next;free(p);
}return 1;
}
int qInsertLast(QUEUE *q, void *e, int size){QUEUE p;
if (!qInsertFirst(q,e,size))return 0;
*q=(*q)->next;return 1;
}
QUEUE qBrowse(QUEUE q, int (*found)(QUEUE, void *),void *data){QUEUE p;int stop;
if (qIsNotEmpty(q))
{p=q;while (! (stop=(*found)(p,data) ) &&
(p=p->next)!=q );if (stop)
return p;}return NULL;
}
-
7/27/2019 8puzzle codigo
9/21
int qDelete(QUEUE *q, QUEUE pos){if (qIsEmpty(*q) || qIsEmpty(pos) ) return 0;
if (pos->next==*q){*q=pos;
return qDeleteFirst(q);}
return qDeleteFirst(&pos);}
int qMove(QUEUE *q1, QUEUE *q2, int (*movethis)(void *elem),int size){QUEUE p;
p=qEMPTY;while (qIsNotEmpty(*q1)){
if ((*movethis)((void *)(*q1)->next->data)){ if (!qInsertLast(q2,(void *)((*q1)->next->data),size)) return 0;
}else
{ if (!qInsertLast(&p,(void *)((*q1)->next->data),size)) return 0;}
if (!qDeleteFirst(q1)) return 0;}*q1=p;
return 1;}
int qFree(QUEUE *q){while ((*q)!=NULL) qDeleteFirst(q);
}
struct cmpData{void *elem;int (*cmp)(void *, void *);
};
static int FirstIsgeqThan(QUEUE q,void *e){
struct cmpData *d;d=(struct cmpData*)e;return (d->cmp(q->next->data,d->elem)>=0);
}
int qOrderedInsert(QUEUE *q, void *e, int size,int (*cmp)(void *, void*),
char repeating){QUEUE p;
-
7/27/2019 8puzzle codigo
10/21
struct cmpData d;
d.cmp=cmp;d.elem=e;p=qBrowse(*q,FirstIsgeqThan,&d);if (p==NULL)qInsertLast(q,e,size);
else{
if (!repeating && cmp(p->next->data,e)==0) return 0;qInsertAt(q,p,e,size);
}return 1;
}
int qDeleteThoseThat(QUEUE *q,int (*DeleteThis)(QUEUE,void *),void *data){QUEUE p;char InFirst;int n=0;
if (qIsNotEmpty(*q)){p=*q;InFirst=1;do{
if (DeleteThis(p,data)){qDelete(q,p);n++;if (InFirst) InFirst=(p==*q);
}else
{p=p->next;InFirst=0;
}} while(qIsNotEmpty(*q) && (p!=*q || InFirst));
}return n;
}
static int CopyElem(QUEUE q,void *e){qInsertLast(&qAux,q->next->data,*(int *)e);
return 0;}
QUEUE qCopy(QUEUE q,int size){qAux=qEMPTY;qBrowse(q,CopyElem,&size);return qAux;
}
-
7/27/2019 8puzzle codigo
11/21
#define COPY(Q) qInsertLast(&qAux,(Q)->data,size)#define MOVE(Q) (Q)=(Q)->next;
QUEUE qMerge(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *),charrepeating){
QUEUE qOld,rOld,qNextOld,rNextOld;int comp;
if (qIsEmpty(q))if (qIsEmpty(r)) return qEMPTY;else return qCopy(r,size);
if (qIsEmpty(r)) return qCopy(q,size);
/* Momentaneously break the round links */BREAKLINK(q,qOld,qNextOld);BREAKLINK(r,rOld,rNextOld);
qAux=qEMPTY;while (q!=qEMPTY && r!=qEMPTY){comp=cmp(q->data,r->data);
if (comp0) {COPY(r); MOVE(r);}else {
COPY(q);if (repeating) COPY(r);MOVE(q); MOVE(r);}
}
while (q!=qEMPTY) {COPY(q); MOVE(q);}while (r!=qEMPTY) {COPY(r); MOVE(r);}
/* Restore round links */qOld->next=qNextOld;rOld->next=rNextOld;
return qAux;}
QUEUE qIntersect(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *)){QUEUE qOld,rOld,qNextOld,rNextOld;
int comp;
if (qIsEmpty(q)||qIsEmpty(r)) return qEMPTY;
/* Momentaneously break the round links */BREAKLINK(q,qOld,qNextOld);BREAKLINK(r,rOld,rNextOld);
qAux=qEMPTY;while (q!=qEMPTY && r!=qEMPTY)
-
7/27/2019 8puzzle codigo
12/21
{
comp=cmp(q->data,r->data);if (comp0) {MOVE(r);}else {COPY(q); MOVE(q); MOVE(r);}
}
/* Restore round links */qOld->next=qNextOld;rOld->next=rNextOld;
return qAux;}
QUEUE qDiff(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *)){QUEUE qOld,rOld,qNextOld,rNextOld;int comp;
if (qIsEmpty(q)) return qEMPTY;if (qIsEmpty(r)) return qCopy(q,size);
/* Momentaneously break the round links */BREAKLINK(q,qOld,qNextOld);BREAKLINK(r,rOld,rNextOld);
qAux=qEMPTY;while (q!=qEMPTY && r!=qEMPTY){comp=cmp(q->data,r->data);if (comp0) {MOVE(r);}else {MOVE(q); MOVE(r);}
}
while (q!=qEMPTY) {COPY(q); MOVE(q);}
/* Restore round links */qOld->next=qNextOld;rOld->next=rNextOld;
return qAux;}
static int CountElem(QUEUE q,void *e)
{*(unsigned int *)e+=1;return 0;
}
unsigned int qCount(QUEUE q){unsigned int c=0;qBrowse(q,CountElem,(void*)&c);return c;
-
7/27/2019 8puzzle codigo
13/21
-
7/27/2019 8puzzle codigo
14/21
typedef struct tHashEntry_ {void *key; /* Pointer to key */void *data; /* Pointer to data */
} tHashEntry;
/*----------------------------------------------------------------
Creates a hash table 'numLists' lists (use a prime number), and'keySize' fixed size for all keysREQUIRES 'numLists' should be a prime number.RETURNS the pointer to the hash table structure.
*/tHashTable *hashCreate(unsigned int numLists,unsigned int keySize);
/*----------------------------------------------------------------Inserts an element in the hash table. For computing the hash value,it will use h->keySize bytes beginning at the 'key' pointer. The
'data'will be stored just as a pointer. If 'data' is not used, fix it to
NULL.
REQUIRES pointer 'h' must point to a correctly created non-null hashstructure.
RETURNS 1 if the element is inserted, 0 if the key was already in thetable.*/int hashInsert(tHashTable *h,void *key, void *data);
/*----------------------------------------------------------------Searchs for entry 'e'.REQUIRES e->key should contain the searched key.
The value of e->data before calling is irrelevant.RETURNS 0 if key was not found.
1 if key was found.
If found, the corresponding data pointer is stored in e->data.*/int hashFind(tHashTable *h,tHashEntry *e);
/*----------------------------------------------------------------Frees memory assigned to the hash table.It will NOT free the assigned memory to each element key and element
data,just the structures that exclusively correspond to the hash table
structure.*/void hashFree(tHashTable *h);
//////////////hash.c
-
7/27/2019 8puzzle codigo
15/21
#include "queue.h"#include "hash.h"
/*----------------------------------------------------------------Creates a hash table 'numLists' lists (use a prime number), and'keySize' fixed size for all keysREQUIRES 'numLists' should be a prime number.
RETURNS the pointer to the hash table structure.*/tHashTable *hashCreate(unsigned int numLists,unsigned int keySize){tHashTable *h=(tHashTable *) malloc(sizeof(tHashTable));h->lists=(QUEUE *)calloc(numLists,sizeof(QUEUE));h->numLists=numLists;h->keySize=keySize;
return h;}
/* Compares two hash entries using their keys. The key size ismomentarily
stored in the static var 'auxKeySize'.*/static unsigned int auxKeySize;static int entryCmp(void *e1, void *e2) {return memcmp(((tHashEntry *)e1)->key,((tHashEntry *)e2)-
>key,auxKeySize);}
/* Computes the hash value for a given key */static unsigned int hv(tHashTable *h,void *key) {int n=sizeof(unsigned int);union {
unsigned int x;char p[n];
} u;
unsigned int sum=0;
int i;char *q=key;
for (i=0;ikeySize/n;i++,q+=n) {memcpy(u.p,q,n);sum+=u.x;
}
for (i=0;ikeySize % n);sum += u.x;
return sum % h->numLists;}
/*----------------------------------------------------------------Inserts an element in the hash table. For computing the hash value,
-
7/27/2019 8puzzle codigo
16/21
it will use h->keySize bytes beginning at the 'key' pointer. The'data'
will be stored just as a pointer. If 'data' is not used, fix it toNULL.
REQUIRES pointer 'h' must point to a correctly created non-null hashstructure.
RETURNS 1 if the element is inserted, 0 if the key was already in the
table.*/int hashInsert(tHashTable *h,void *key, void *data) {tHashEntry e;e.key=key;e.data=data;auxKeySize=h->keySize;return qOrderedInsert(&h-
>lists[hv(h,key)],&e,sizeof(tHashEntry),entryCmp,0);}
/* Searchs the first entry which is greater or equal than e */static int geqEntry(QUEUE q, void *e) {
return entryCmp(qFirst(q,tHashEntry),e)>=0;}
/*----------------------------------------------------------------Searchs for entry 'e'.REQUIRES e->key should contain the searched key.
The value of e->data before calling is irrelevant.RETURNS 0 if key was not found.
1 if key was found.If found, the corresponding data pointer is stored in e-
>data.*/int hashFind(tHashTable *h,tHashEntry *e) {QUEUE aux;
/* Ordered search in the corresponding list */auxKeySize=h->keySize;aux=qBrowse(h->lists[hv(h,e->key)],geqEntry,e);
if (aux!=qEMPTY && entryCmp(qFirst(aux,tHashEntry),e)==0) {e->data=qFirst(aux,tHashEntry)->data;return 1;
}
return 0; /* not found */}
/*----------------------------------------------------------------
Frees memory assigned to the hash table.It will NOT free the assigned memory to each element key and element
data,just the structures that exclusively correspond to the hash table
structure.*/void hashFree(tHashTable *h) {/* Delete all lists */int i;for (i=0;inumLists;i++)
-
7/27/2019 8puzzle codigo
17/21
while (qIsNotEmpty(h->lists[i]))qDeleteFirst(&h->lists[i]);
free(h->lists); /* Free the lists array */free(h); /* Free the hash table structure */
}
///////////////search.c
#include #include #include "queue.h"#include "hash.h"#include "domain.h"#include "search.h"#include
#include
struct {enum {BREADTH,DEPTH} fringeInsertion;int (*algorithm)();char verbose;
} options;
struct {unsigned int expandedNodes;struct rusage resources;
} statistics;
int inPath(tSearchNode *node,tState *s) {while (node!=NULL) {if (stateEqual(node->state,s)) return 1;node=node->parent;
}return 0;
}
QUEUE expand(tSearchNode *node) {QUEUE successors=qEMPTY;unsigned op;
for (op=0;opstate)) {tSearchNode *new;tState *s=successorState(op,node->state);
if (options.fringeInsertion==DEPTH && inPath(node->parent,s))free(s);
else {new=(tSearchNode *)malloc(sizeof(tSearchNode));new->state=s;new->parent=node;
-
7/27/2019 8puzzle codigo
18/21
new->action=op;new->pathCost=node->pathCost + cost(op,node->state);new->depth=node->depth+1;
qInsertLast(&successors,&new,sizeof(tSearchNode *));}
}
statistics.expandedNodes++;return successors;
}
void printReversePath(tSearchNode *node) {if (node->parent==NULL) return;
printReversePath(node->parent);showOperator(node->action);if (options.verbose) {printf("\n");
showState(node->state);printf("\n");
}else printf("; ");
}
void printSolution(tSearchNode *node) {printf("Solution: \n");printReversePath(node);printf("\nDepth=%d\n",node->depth);printf("Cost=%d\n",node->pathCost);
}
void insertNode(QUEUE *fringe,tSearchNode **n) {switch(options.fringeInsertion) {case BREADTH:
qInsertLast(fringe,n,sizeof(tSearchNode *)); break;case DEPTH:
qInsertFirst(fringe,n,sizeof(tSearchNode *)); break;}
}
tSearchNode *rootNode() {/* Create the root node */
tSearchNode *root=(tSearchNode *)malloc(sizeof(tSearchNode));root->state=initialState();root->parent=NULL;root->pathCost=0;root->depth=0;return root;
}
int treeSearch() {tSearchNode *node,*n,*root=rootNode();
-
7/27/2019 8puzzle codigo
19/21
QUEUE fringe=qEMPTY,successors;
qInsertFirst(&fringe,&root,sizeof(tSearchNode *));while (1) {if (qIsEmpty(fringe)) return 0;qPOP(&fringe,&node,sizeof(tSearchNode *));
if (goalTest(node->state)) {printSolution(node); return 1;}
successors = expand(node);while (!qIsEmpty(successors)) {
qPOP(&successors,&n,sizeof(tSearchNode *));insertNode(&fringe,&n);
}}
}
int graphSearch() {tSearchNode *node,*n,*root=rootNode();
QUEUE fringe=qEMPTY,successors;tHashTable *closed=hashCreate(10007,sizeof(tState));tHashEntry e;
qInsertFirst(&fringe,&root,sizeof(tSearchNode *));
while (1) {if (qIsEmpty(fringe)) return 0;qPOP(&fringe,&node,sizeof(tSearchNode *));
if (goalTest(node->state)) {printSolution(node); return 1;}
e.key=node->state;if (hashFind(closed,&e)) { /* already visited state */
free(node->state);free(node);continue;
}
hashInsert(closed,node->state,NULL);
successors = expand(node);while (!qIsEmpty(successors)) {
qPOP(&successors,&n,sizeof(tSearchNode *));insertNode(&fringe,&n);
}}
}
extern char *optarg;extern int optind;
int main (int argc,char *argv[]) {/* Processing options */int c;
-
7/27/2019 8puzzle codigo
20/21
options.algorithm=treeSearch;options.fringeInsertion=BREADTH;options.verbose=0;statistics.expandedNodes=0;
while ((c = getopt(argc, argv, "a:f:v")) != EOF) {switch (c) {
case 'a':if (!strcmp(optarg,"tree"))options.algorithm=treeSearch;
else {if (!strcmp(optarg,"graph"))
options.algorithm=graphSearch;else {
printf("Unrecognized algorithm %s.\n",optarg); exit(1);}
}break;
case 'f':if (!strcmp(optarg,"breadth"))
options.fringeInsertion=BREADTH;else {if (!strcmp(optarg,"depth"))
options.fringeInsertion=DEPTH;else {
printf("Unrecognized type of fringe insertion%s.\n",optarg); exit(1);
}}break;
case 'v': options.verbose=1;break;case 'h':case '?':
printf("search -a -f ");
}}
if (!(options.algorithm()))printf("No solution.\n");
printf("%d expanded nodes.\n",statistics.expandedNodes);getrusage(RUSAGE_SELF,&statistics.resources);printf("%ld.%03ld seconds.\n",statistics.resources.ru_utime.tv_sec,statistics.resources.ru_utime.tv_usec/1000);
}
////////////////search.h
tState *initialState();int goalTest(tState *s);int executable(unsigned op,tState *s);tState *successorState(unsigned op,tState *s);int cost(unsigned op,tState *s);
-
7/27/2019 8puzzle codigo
21/21
void showOperator(unsigned op);void showState(tState *s);
/////////////////////////////////////////////////////////////////////////////////NOSE PARA QUE ES
SOURCES=queue.c domain.c search.c hash.cINCLUDES=$(SRCS:%.c=%.h)
search : $(INCLUDES) $(SOURCES)gcc -o search $(SOURCES)
debug : $(INCLUDES) $(SOURCES)gcc -ggdb -o search $(SOURCES)
domain :rm -f domain.c domain.hln -s $(DOM).c domain.cln -s $(DOM).h domain.htouch domain.c
clean :rm -f search *.o