中级农民
积分 101
大米 颗
鳄梨 个
水井 尺
蓝莓 颗
萝卜 根
小米 粒
学分 个
注册时间 2011-11-28
最后登录 1970-1-1
注册一亩三分地论坛,查看更多干货!
您需要 登录 才可以下载或查看附件。没有帐号?注册账号
x
最近在做final project for intro to C,让做一个hangman游戏,就是猜一个单词中的字母,猜错了画个吊死的小人那个游戏(link to wiki ),要求可以让用户猜,也可以让电脑猜,单词表从一个外部文件读进来。我已经写好了这个程序,但是电脑猜这一部分我觉得有点问题,就是用的策略太笨了,我的办法是先让计算机算出所有字母的频率,然后从高到低猜,我觉得这样不太smart,但是一时想不出更好的办法。
代码我贴在下面了,运行时需要的另外两个文件我也附在附件里,小弟在这里请大家帮忙想想办法,看看有没有更好的策略,第二也是想让各位对我的代码提点意见,风格上是不是不太好。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAXLEN 50
#define SCREEN "hangman.txt"
#define DICT "dict.txt"
#define TRI 12
typedef struct screen{
char pixel[65][15];
}screen;
typedef struct dicent{
long int index;
char* entry;
struct dicent* next;
}dicent;
typedef struct sentence{
char words[MAXLEN];
int x;
int y;
}sentence;
screen loadscreen(FILE* filptr);
//It loads a screen from a file.
void printscreen(screen current);
//It output a screen.
int askcommand(int state);
//It asks users to input a command.
int userguess(screen current,int state);
//It is the user guess routine.
int computerguess(screen current,int state);
//It is the computer guess routine.
int readict(FILE *filptr,dicent* head);
//It reads the dictionary.
int randword(dicent* head,char* wordsel,int number);
//It gives a random word.
screen setscreen(screen current,int ulx,int uly,int drx,int dry);
//It sets certain area to blank.
screen sentosrc(screen current,sentence temp);
//It sets certain words to screen.
screen chartosrc(screen current,char letter,int locx,int locy);
//It sets certain letter to certain location.
int checkletter(char letter);
//It checks whether the letter is illegal or not.
void setchecklist(void);
//It set the check list to all 0s.
void setchance(int* chance,dicent* head);
//It caculates out every letter's chances.
int checklist[26]={0};
int main(void){
int state=0;
FILE* toscr;
screen current;
toscr=fopen(SCREEN,"r");
if(toscr==NULL){state=-1;}
while(state!=3)
{
if(state==-1){
system("cls");
printf("Program need hangman.txt\n");
exit(1);
}
if(state==-2){
printf("There is something wrong with your input,\nSorry but I have to force you to quit\n");
exit(1);
}
if(state==-3){
printf("Program need dict.txt\n");
exit(1);
}
if(state==0){current=loadscreen(toscr);}
printscreen(current);
state=askcommand(state);
if(state==1)
{state=userguess(current,state);setchecklist();}
if(state==2)
{state=computerguess(current,state);}
}
fcloseall();
if(state==3)
{return 0;}
else
{return 1;}
}
screen loadscreen(FILE* filptr){
int i,j;
screen target;
for(j=0;j<15;j++){
for(i=0;i<65;i++)
{target.pixel[i][j]=fgetc(filptr);}
}
rewind(filptr);
return target;
}
void printscreen(screen cureent){
int i,j;
system("cls");
for(j=0;j<15;j++){
for(i=0;i<65;i++){
putchar(cureent.pixel[i][j]);
}
}
}
int askcommand(int state){
char command;
if(state==0){
printf("Input command here:");
fflush(stdin);
command=getchar();
state=command-'0';
}
if(state==4){
printf("Try your letter(lower case please):");
fflush(stdin);
command=getchar();
if(command>='a'&&command<='z')return command;
else return -2;
}
if(state==7){
printf("Please input the number of letters in your word:");
fflush(stdin);
command=getchar();
if(command>'0'&&command<=('0'+MAXLEN))return (command-'0');
else return -2;
}
if(state==9){
fflush(stdin);
command=getchar();
if(command=='y'||command=='n')return command;
else return -2;
}
if(state==10){
printf("Now I need the position of the letter:\n");
fflush(stdin);
command=getchar();
if(command>='0')return (command-'0'-1);
else return -2;
}
if(state==11){
printf("Please input the position,if you have done with the input plesase input 0\n");
fflush(stdin);
command=getchar();
if(command>='0')return (command-'0'-1);
else return -2;
}
if(state!=3&&state!=2&&state!=1) state=-2;
return state;
}
int userguess(screen current,int state){
int i,j=0,flag=0,success=0,trial=0;
FILE *todict;
sentence temp;
long int number,wordlen=0;
char wordsel[MAXLEN],letter;
dicent* head,* ptr,*te;
todict=fopen(DICT,"r");
head=(dicent *)malloc(sizeof(dicent));
if(todict==NULL){state=-3;}
else{
state=4;
number=readict(todict,head);
wordlen=randword(head,wordsel,number);
current=setscreen(current,0,3,27,11);
strcpy(temp.words,"The word for you:");
temp.x=0;
temp.y=3;
current=sentosrc(current,temp);
strcpy(temp.words," ");
for(i=0;i<strlen(wordsel);i++)
{
temp.words[i]='_';
}
temp.x=0;
temp.y=4;
current=sentosrc(current,temp);
strcpy(temp.words,"Worng letters:");
temp.x=0;
temp.y=5;
current=sentosrc(current,temp);
printscreen(current);
while(success!=strlen(wordsel)&&state!=-2&&trial<TRI){
printscreen(current);
printf("You have used %d/%d trials\n",trial,TRI);
printf("The word contains %d letters.\n",strlen(wordsel));
letter=askcommand(state);
if(letter==-2)state=-2;
else{
if(checkletter(letter)){
flag=0;
for(i=0;i<strlen(wordsel);i++){
if(letter==wordsel[i]){
current=chartosrc(current,letter,i,4);
printscreen(current);
success++;
flag=1;
}}
if(flag==0){current=chartosrc(current,letter,j,6);j++;}}
else{
printf("You have input the letter once.\nPlease press any key to continue.");
fflush(stdin);
getchar();}
}
trial++;
}
}
if(trial==TRI)state=5;
if(success==strlen(wordsel))state=6;
//notice!!
if(state==5){
strcpy(temp.words,wordsel);
temp.x=0;
temp.y=4;
current=sentosrc(current,temp);
printscreen(current);
printf("Sorry you have used up your chance.\n");
printf("Please press any key to get back to main menu.\n");
fflush(stdin);
getchar();
state=0;
}
if(state==6){
printf("Bravo!You are good at this!\n");
printf("Please press any key to get back to main menu.\n");
fflush(stdin);
getchar();
state=0;
}
ptr=head;
while(ptr->next!=NULL)
{
te=ptr->next;
free(ptr);
ptr=te;
}
free(te);
fclose(todict);
return state;
}
int readict(FILE* filptr,dicent* head){
long int number=0;
char temp[MAXLEN];
dicent* ptr;
ptr=head;
while(fscanf(filptr,"%s",temp)!=EOF){
ptr->index=number;
ptr->entry=(char *)malloc(MAXLEN*sizeof(char));
strcpy(ptr->entry,temp);
ptr->next=(dicent *)malloc(sizeof(dicent));
ptr=ptr->next;
number++;
}
ptr->next=NULL;
rewind(filptr);
return number;
}
int randword(dicent* head,char* wordsel,int number){
dicent* ptr;
int len,tag;
ptr=head;
srand((unsigned)time(NULL));
tag=rand()%number;
while(ptr->index!=tag){
ptr=ptr->next;
}
strcpy(wordsel,ptr->entry);
len=strlen(wordsel);
return len;
}
screen setscreen(screen current,int ulx,int uly,int drx,int dry){
int i,j;
for(j=uly;j<=dry;j++){
for(i=ulx;i<=drx;i++){
current.pixel[i][j]=' ';
}
}
return current;
}
screen sentosrc(screen current,sentence temp){
int i;
for(i=temp.x;i<(temp.x+strlen(temp.words));i++)
{
current.pixel[i][temp.y]=temp.words[i-temp.x];
}
return current;
}
screen chartosrc(screen current,char letter,int locx,int locy){
current.pixel[locx][locy]=letter;
return current;
}
int checkletter(char letter){
if(checklist[letter-'a']==0){checklist[letter-'a']=1;return 1;}
else return 0;
}
void setchecklist(void){
int i;
for(i=0;i<26;i++)
{checklist[i]=0;}
}
int computerguess(screen current,int state){
int i,number,success=0,flag=0,len,chance[26]={0},tem,pos;
FILE *todict;
sentence temp;
dicent* head,* ptr,*te;
char letter,command;
todict=fopen(DICT,"r");
head=(dicent *)malloc(sizeof(dicent));
if(todict==NULL){state=-3;}
else{
state=7;
number=readict(todict,head);
setchance(chance,head);
current=setscreen(current,0,3,27,11);
printscreen(current);
strcpy(temp.words,"Hi!I am to guess your word!");
temp.x=0;
temp.y=3;
current=sentosrc(current,temp);
strcpy(temp.words,"Your Word:");
temp.x=0;
temp.y=4;
current=sentosrc(current,temp);
strcpy(temp.words," ");
len=askcommand(state);
if(len==-2){state=-2;}
for(i=0;i<len;i++)
{
temp.words[i]='_';
}
temp.x=0;
temp.y=5;
current=sentosrc(current,temp);
printscreen(current);
flag=0;
while(success<len&&state!=-2&&flag<TRI){
state=9;
printscreen(current);
printf("This is the computer's %d/%d trial\n",flag+1,TRI);
flag++;
tem=0;
for(i=0;i<26;i++){
if(tem<chance[i]){tem=chance[i];letter='a'+i;}
}
chance[letter-'a']=0;
printf("Humm...My guess is %c,is it right(y/n)?\n",letter);//notice!
if((command=askcommand(state))=='y'){
printscreen(current);
state=10;
pos=askcommand(state);//tested
if(pos!=-2&&pos<len){
success++;
current=chartosrc(current,letter,pos,5);
printscreen(current);
}
else {state=-2;break;}
printf("Is there any more this letter(y/n)?\n");
command=askcommand(9);//tested
if(command==-2){state=-2;break;}
else{
if(command=='y'){
state=11;
while(state==11){
pos=askcommand(state);
if(pos==-1)state=0;
else{
if(pos==-2||pos>=len){state=-2;break;}
else{
success++;
current=chartosrc(current,letter,pos,5);
printscreen(current);
}}}}
if(command=='n')state=0;
}
}
else{
if(command=='n')state=0;
if(command==-2)state=-2;
}
}
}
if(success==len){state=8;}
else if(success>=0&&state!=-2)state=12;
if(state==8){
printf("Computer is so smart!!\n");
printf("Please press any key to get back to main menu.\n");
fflush(stdin);
getchar();
state=0;
}
if(state==12){
printf("I have lost the game :-(\n");
printf("Please press any key to get back to main menu.\n");
fflush(stdin);
getchar();
state=0;
}
ptr=head;
while(ptr->next!=NULL)
{
te=ptr->next;
free(ptr);
ptr=te;
}
free(te);
fclose(todict);
return state;
}
void setchance(int* chance,dicent* head){
int i=0,j=0;
dicent *ptr;
char temp[MAXLEN];
ptr=head;
while(ptr->next!=NULL){
strcpy(temp,ptr->entry);
i=0;
while(*(temp+i)!='\0'){
for(j=0;j<26;j++){
if(*(temp+i)=='a'+j||*(temp+i)=='A'+j)
{(*(chance+j))++;break;}
}
i++;
}
ptr=ptr->next;
}
}
复制代码
上一篇:
关于程序抄袭雷同的问题 下一篇:
拿到AD, 惶恐!! , 毕竟离毕业多年了---有70后的介绍下经验