void board_flag(Board *bd) { Data *data = bd->data+(bd->w*bd->cury + bd->curx); if (data->open) { bel(); return; } data->flag = !data->flag; bd->nflags += 2*data->flag - 1; }
bool board_open(Board *bd) { Data *data = bd->data + (bd->w*bd->cury + bd->curx); if (bd->startTime == -1) { board_gen(bd, bd->curx, bd->cury); } if (data->flag || data->open) { bel(); return false; } else if (data->bomb) { return true; } board_flood(bd, bd->curx, bd->cury); return false; }
void startsingleplayer(){ const int player=ORDER; clearscreen(); moveto(0,0); setbold(true); tprintf("Order & Chaos -- Single player"); setbold(false); Board *board=makeboard(); int curx=0,cury=0; bool aiturn=false; Move mv; int win=-1; while(true){ moveto(2,2); tprintboard(board); redraw(); if(win!=-1)break; if(aiturn){ aiturn=false; moveto(0,N+3); tprintf("Calculating..."); redraw(); mv=calcmove(board,!player); applymove(board,mv); win=checkwin(board); if(win!=-1)break; moveto(0,N+3); tprintf(" "); continue; } moveto(2+2*curx,2+cury); redraw(); int key=tgetkey(); int stone; switch(key){ case 'q': moveto(0,N+3); setbold(true); tprintf("Really quit? [y/N] "); setbold(false); redraw(); key=tgetkey(); if(key=='y'||key=='Y')return; moveto(0,N+3); tprintf(" "); break; case 'h': case KEY_LEFT: if(curx>0)curx--; else bel(); break; case 'j': case KEY_DOWN: if(cury<N-1)cury++; else bel(); break; case 'k': case KEY_UP: if(cury>0)cury--; else bel(); break; case 'l': case KEY_RIGHT: if(curx<N-1)curx++; else bel(); break; case 'x': stone=XX; if(false){ case 'o': stone=OO; } if(!isempty(board,N*cury+curx)){ bel(); break; } mv.pos=N*cury+curx; mv.stone=stone; applymove(board,mv); win=checkwin(board); if(win!=-1)break; aiturn=true; break; default: bel(); break; } } moveto(0,N+3); setbold(true); const char *plstr=win==ORDER?"Order":"Chaos"; if(win==player)tprintf("You (%s) won! Congratulations!",plstr); else tprintf("The AI (%s) won! Better next time...",plstr); setbold(false); redraw(); tgetkey(); }
int main(int argc, char **argv) { struct timeval tv; gettimeofday(&tv, NULL); srand(tv.tv_sec*1000000ULL + tv.tv_usec); if (argc >= 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) { fprintf(stderr, "Usage: %s [width] [height] [nbombs]\n", argv[0]); return 1; } int width = DEF_WIDTH; int height = DEF_HEIGHT; int nbombs = -1; for (int i = 1; i < argc; i++) { int val = atoi(argv[i]); switch (i) { case 1: width = val; break; case 2: height = val; break; case 3: nbombs = val; break; } } if (nbombs == -1) { nbombs = .123 * width * height; } if (nbombs >= width*height) { fprintf(stderr, "nbombs (=%d) more than or equal to width * height (=%d)\n", nbombs, width*height); return 1; } initscreen(); atexit(endscreen); signal(SIGINT, signalend); Board *bd=board_make(width, height, nbombs); Key key; bool quit = false; int repeat = 1; bool have_repeat_num = false; while (!quit) { board_draw(bd); if (board_win(bd)) { char *timestamp; formatTime(×tamp, time(NULL) - bd->startTime); if (!prompt_playagain("You win!", timestamp, height + 2)) { break; } board_destroy(bd); bd = board_make(width, height, nbombs); continue; } getkey(&key); switch (key.type) { case KNUM: if (have_repeat_num) { if (repeat >= (INT_MAX - key.num) / 10) { // would overflow bel(); repeat = 1; have_repeat_num = false; } else { repeat = 10 * repeat + key.num; } } else if (key.num >= 1) { repeat = key.num; have_repeat_num = true; } break; case KARROW: board_shiftcursor(bd, key.dir, repeat); repeat = 1; have_repeat_num = false; break; case KCHAR: switch (key.ch) { case 'q': prompt_quit(height + 2); break; case 'f': board_flag(bd); break; case 'r': board_destroy(bd); bd=board_make(width, height, nbombs); break; case ' ': if (!board_open(bd)) break; board_revealbombs(bd); char *timestamp; formatTime(×tamp, time(NULL) - bd->startTime); if (!prompt_playagain("BOOM!", timestamp, height + 2)) { quit = true; break; } board_destroy(bd); bd = board_make(width, height, nbombs); break; } if (have_repeat_num) bel(); repeat = 1; have_repeat_num = false; break; default: bel(); if (have_repeat_num) bel(); repeat = 1; have_repeat_num = false; break; } } board_destroy(bd); }