📄 server.c
字号:
/*---------------------------------------------------------------------- File : server.c Contents: hamster control functions, server side Author : Christian Borgelt History : 14.10.1997 file created 16.10.1997 first version completed 18.10.1997 adapted to opaque hamster structure 19.10.1997 score computation added 22.10.1997 penalty for crash against wall added 31.10.1997 minor improvements 01.11.1997 parameters x and y removed from hms_create 15.01.1998 corn heap check in function hms_drop adapted 17.01.1998 counter for crashes against walls added 27.01.1998 range checks for score added----------------------------------------------------------------------*/#include <stdlib.h>#include <limits.h>#include "server.h"/*---------------------------------------------------------------------- Preprocessor Definitions----------------------------------------------------------------------*/#define CORNWORTH 20 /* worth of one piece of corn */#define MOVEPENALTY 1 /* penalty for (field to field) move */#define CRASHPENALTY 20 /* penalty for crash against a wall *//*---------------------------------------------------------------------- Constants----------------------------------------------------------------------*/static short walls[4] = { MZ_EAST, MZ_NORTH, MZ_WEST, MZ_SOUTH };/*---------------------------------------------------------------------- Functions----------------------------------------------------------------------*/HAMSTER* hms_create (MAZE *maze, int id, int dir, DISPFN disp){ /* --- create a hamster */ HAMSTER *hms; /* created hamster */ hms = (HAMSTER*)malloc(sizeof(HAMSTER)); if (!hms) return NULL; /* allocate memory and */ hms->id = id; /* initialize fields */ hms->dir = dir; hms->x = 0; hms->y = 0; hms->load = hms->corncnt = 0; hms->movecnt = hms->crshcnt = 0; hms->score = 0; /* clear load, counters, and score */ hms->maze = maze; /* note maze and display function */ hms->disp = disp; /* and call display function */ if (disp) disp(hms, HMS_CREATED, 0); return hms; /* return created hamster */} /* hms_create() *//*--------------------------------------------------------------------*/void hms_delete (HAMSTER *hms){ /* --- delete a hamster */ if (hms->disp) hms->disp(hms, HMS_DELETED, 0); free(hms); /* deallocate memory */} /* hms_delete() *//*--------------------------------------------------------------------*/void hms_pos (HAMSTER *hms, int *x, int *y){ /* --- get hamster position */ *x = hms->x; *y = hms->y; /* return relative coordinates */} /* hms_pos() *//*--------------------------------------------------------------------*/int hms_dir (HAMSTER *hms){ /* --- get hamster direction */ return hms->dir; /* return current direction */} /* hms_dir() *//*--------------------------------------------------------------------*/int hms_load (HAMSTER *hms){ /* --- get hamster load */ return hms->load; /* return current corn load */} /* hms_load() *//*--------------------------------------------------------------------*/int hms_corn (HAMSTER *hms){ /* --- check for corn */ int x, y; /* coordinates of start position */ mz_getpos(hms->maze, &x, &y); /* get number of items on field */ return mz_getfld(hms->maze, x +hms->x, y +hms->y) & MZ_ITEMS;} /* hms_corn() *//*--------------------------------------------------------------------*/int hms_look (HAMSTER *hms){ /* --- take a look ahead */ int x, y; /* absolute coordinates */ mz_getpos(hms->maze, &x, &y); /* get coordinates of start position */ x += hms->x; y += hms->y; /* and compute absolute coordinates */ if (mz_getfld(hms->maze, x, y) & walls[hms->dir]) return HMS_WALL; /* test for a wall ahead */ switch (hms->dir) { /* evaluate hamster direction */ case HMS_EAST : x++; break; case HMS_NORTH: y++; break; case HMS_WEST : x--; break; case HMS_SOUTH: y--; break; } /* get coordinates of field ahead */ return (mz_getfld(hms->maze, x, y) & MZ_ITEMS) ? HMS_CORN : HMS_EMPTY; /* test for corn on field ahead */} /* hms_look() *//*--------------------------------------------------------------------*/int hms_move (HAMSTER *hms){ /* --- move hamster one field */ int x, y; /* absolute coordinates */ mz_getpos(hms->maze, &x, &y); /* get coordinates of start position */ x += hms->x; y += hms->y; /* and compute absolute coordinates */ if (mz_getfld(hms->maze, x, y) & walls[hms->dir]) { hms->crshcnt++; /* if there is a wall ahead */ hms->score = (hms->score < INT_MIN +CRASHPENALTY) ? INT_MIN : (hms->score -CRASHPENALTY); /* count crash and compute new score */ if (hms->disp) hms->disp(hms, HMS_SCORED, -CRASHPENALTY); return -1; /* add penalty for crash to score, */ } /* display new score, and abort */ switch (hms->dir) { /* evaluate hamster direction */ case HMS_EAST : hms->x++; break; case HMS_NORTH: hms->y++; break; case HMS_WEST : hms->x--; break; case HMS_SOUTH: hms->y--; break; } /* move hamster to new field */ hms->movecnt++; /* count move and compute score */ hms->score = (hms->score < INT_MIN +MOVEPENALTY) ? INT_MIN : (hms->score -MOVEPENALTY); if (hms->disp) { /* if display function given */ hms->disp(hms, HMS_MOVED, hms->dir); hms->disp(hms, HMS_SCORED, -MOVEPENALTY); } /* update display */ return 0; /* return 'ok' */} /* hms_move() *//*--------------------------------------------------------------------*/void hms_turn (HAMSTER *hms, int turn){ /* --- turn hamster 90 degrees */ hms->dir = (hms->dir +((turn >= 0) ? 1 : 3)) % 4; if (hms->disp) /* compute new direction */ hms->disp(hms, HMS_TURNED, (turn >= 0) ? HMS_POS : HMS_NEG);} /* hms_turn() *//*--------------------------------------------------------------------*/int hms_take (HAMSTER *hms, int amount){ /* --- take some corn */ int x, y; /* absolute coordinates */ short heap; /* size of corn heap on field */ if (amount < 0) /* if amount is negative, drop corn */ return -hms_drop(hms, -amount); mz_getpos(hms->maze, &x, &y); /* get coordinates of start position */ x += hms->x; y += hms->y; /* and compute absolute coordinates */ heap = mz_getfld(hms->maze, x, y) & MZ_ITEMS; if (amount > heap) /* check amount against size of */ amount = heap; /* corn heap and cheek capacity */ if (hms->load +amount > HMS_MAXLOAD) amount = HMS_MAXLOAD -hms->load; if (amount <= 0) return 0; /* if amount is zero, abort function */ mz_setfld(hms->maze, x, y, MZ_ITEMS, (short)(heap -amount)); hms->load += amount; /* take corn from field into cheeks */ if (hms->disp) hms->disp(hms, HMS_FIELD, 0); return amount; /* return amount taken */} /* hms_take() *//*--------------------------------------------------------------------*/int hms_drop (HAMSTER *hms, int amount){ /* --- drop some corn */ int x, y; /* absolute coordinates */ short heap; /* size of corn heap on field */ int score; /* score for dropped corn */ if (amount < 0) /* if amount is negative, take corn */ return -hms_take(hms, -amount); mz_getpos(hms->maze, &x, &y); /* get coordinates of start position */ x += hms->x; y += hms->y; /* and compute absolute coordinates */ heap = mz_getfld(hms->maze, x, y) & MZ_ITEMS; if (amount > HMS_MAXCORN -heap) /* check amount against */ amount = HMS_MAXCORN -heap; /* maximal size of corn heap */ if (amount > hms->load) /* check amount against */ amount = hms->load; /* current load in cheeks */ if (amount <= 0) return 0; /* if amount is zero, abort function */ if (mz_getfld(hms->maze, x, y) & MZ_HOME) { hms->corncnt += amount; /* if on home field, */ score = CORNWORTH *amount; /* compute and add score */ hms->score = (hms->score > INT_MAX -score) ? INT_MAX : (hms->score +score); if (hms->disp) hms->disp(hms, HMS_SCORED, CORNWORTH *amount); } else { /* if not on home field */ mz_setfld(hms->maze, x, y, MZ_ITEMS, (short)(heap +amount)); if (hms->disp) hms->disp(hms, HMS_FIELD, 0); } /* drop corn from cheeks */ hms->load -= amount; /* into the field */ return amount; /* return amount dropped */} /* hms_drop() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -