| 550 |
550 |
| 551 static int sendmove(GameState *gamestate, int opponent, uint8_t mycolor) { |
551 static int sendmove(GameState *gamestate, int opponent, uint8_t mycolor) { |
| 552 |
552 |
| 553 size_t bufpos = 0; |
553 size_t bufpos = 0; |
| 554 char movestr[MOVESTR_BUFLEN]; |
554 char movestr[MOVESTR_BUFLEN]; |
| |
555 bool remis_offered = false; |
| 555 bool remis_rejected = false; |
556 bool remis_rejected = false; |
| 556 bool remis_suggested = false; |
557 bool remis_suggested = false; |
| 557 bool resign_suggested = false; |
558 bool resign_suggested = false; |
| 558 bool use_premove = false; |
559 bool use_premove = false; |
| 559 uint8_t code; |
560 uint8_t code; |
| 583 } |
584 } |
| 584 } else if (remis_suggested) { |
585 } else if (remis_suggested) { |
| 585 printw("The opponent offers remis. Type remis to accept. \n\n"); |
586 printw("The opponent offers remis. Type remis to accept. \n\n"); |
| 586 } else if (remis_rejected) { |
587 } else if (remis_rejected) { |
| 587 printw("Remis offer rejected. \n\n"); |
588 printw("Remis offer rejected. \n\n"); |
| |
589 } else if (remis_offered) { |
| |
590 printw("Remis offer sent. \n\n"); |
| 588 } else { |
591 } else { |
| 589 printw("Or use a command: remis, resign, savepgn \n\n"); |
592 printw("Or use a command: remis, resign, savepgn \n\n"); |
| 590 } |
593 } |
| 591 printw("Type your move: "); |
594 printw("Type your move: "); |
| 592 clrtoeol(); |
595 clrtoeol(); |
| 593 |
596 |
| 594 /* check if the opponent sent us something */ |
597 /* check if the opponent sent us something */ |
| 595 code = net_recieve_code_async(opponent); |
598 code = net_recieve_code_async(opponent); |
| 596 switch (code) { |
599 switch (code) { |
| 597 case NETCODE_REMIS: |
600 case NETCODE_REMIS: |
| |
601 if (remis_offered) { |
| |
602 gamestate->remis = true; |
| |
603 return 1; |
| |
604 } |
| 598 remis_suggested = true; |
605 remis_suggested = true; |
| 599 break; |
606 break; |
| 600 case NETCODE_TAUNT: |
607 case NETCODE_TAUNT: |
| 601 resign_suggested = true; |
608 resign_suggested = true; |
| 602 break; |
609 break; |
| 640 net_send_code(opponent, NETCODE_REMIS); |
647 net_send_code(opponent, NETCODE_REMIS); |
| 641 gamestate->remis = true; |
648 gamestate->remis = true; |
| 642 return 1; |
649 return 1; |
| 643 } if (!remis_rejected) { |
650 } if (!remis_rejected) { |
| 644 net_send_code(opponent, NETCODE_REMIS); |
651 net_send_code(opponent, NETCODE_REMIS); |
| 645 printw("Remis offer sent - waiting for acceptance..."); |
652 remis_offered = true; |
| 646 refresh(); |
|
| 647 code = net_recieve_code(opponent); |
|
| 648 if (code == NETCODE_ACCEPT) { |
|
| 649 gamestate->remis = true; |
|
| 650 return 1; |
|
| 651 } else if (code == NETCODE_CONNLOST) { |
|
| 652 gamestate->ragequit = true; |
|
| 653 return 1; |
|
| 654 } else { |
|
| 655 remis_rejected = true; |
|
| 656 } |
|
| 657 } |
653 } |
| |
654 /* prevent spamming the remis message */ |
| 658 } else if (movestr[0] == 0) { |
655 } else if (movestr[0] == 0) { |
| 659 /* ignore empty move strings and ask again */ |
656 /* ignore empty move strings and ask again */ |
| 660 } else { |
657 } else { |
| 661 Move move; |
658 Move move; |
| 662 int eval_result = eval_move(gamestate, |
659 int eval_result = eval_move(gamestate, |
| 701 static int recvmove(GameState *gamestate, int opponent, uint8_t mycolor) { |
698 static int recvmove(GameState *gamestate, int opponent, uint8_t mycolor) { |
| 702 memset(gamestate->premove, 0, sizeof(gamestate->premove)); |
699 memset(gamestate->premove, 0, sizeof(gamestate->premove)); |
| 703 |
700 |
| 704 size_t bufpos = 0; |
701 size_t bufpos = 0; |
| 705 char movestr[MOVESTR_BUFLEN]; |
702 char movestr[MOVESTR_BUFLEN]; |
| 706 bool remis_suggested = false, resign_suggested = false; |
703 bool remis_suggested = false, remis_offered = false; |
| |
704 bool resign_suggested = false; |
| 707 while (1) { |
705 while (1) { |
| 708 timecontrol(gamestate); |
706 timecontrol(gamestate); |
| 709 |
707 |
| 710 move(inputy, 0); |
708 move(inputy, 0); |
| 711 printw("Waiting for opponent. Use chess notation to prepare a move.\n"); |
709 printw("Waiting for opponent. Use chess notation to prepare a move.\n"); |
| 712 if (*gamestate->premove) { |
710 if (*gamestate->premove) { |
| 713 printw("Current pre-move: %s \n\n", |
711 printw("Current pre-move: %s \n", |
| 714 gamestate->premove); |
712 gamestate->premove); |
| 715 } else if (remis_suggested && !resign_suggested) { |
713 } else if (remis_suggested && !resign_suggested) { |
| 716 printw("Suggested remis. \n\n"); |
714 printw("Suggested remis. \n"); |
| 717 } else if (resign_suggested) { |
715 } else if (resign_suggested) { |
| 718 if (remis_suggested) { |
716 if (remis_suggested) { |
| 719 printw("Suggested to resign or at least to accept remis. \n\n"); |
717 printw("Suggested to resign or at least to accept remis. \n"); |
| 720 } else { |
718 } else { |
| 721 printw("Suggested to resign. \n\n"); |
719 printw("Suggested to resign. \n"); |
| 722 } |
720 } |
| 723 } else { |
721 } else { |
| 724 printw("Or use a command: remis, resign, taunt, savepgn \n\n"); |
722 printw("Or use a command: remis, resign, taunt, savepgn \n"); |
| |
723 } |
| |
724 if (remis_offered) { |
| |
725 printw("Opponent offered remis. Type 'remis' to accept.\n"); |
| |
726 } else { |
| |
727 printw("\n"); |
| 725 } |
728 } |
| 726 printw("Prepare your next move: "); |
729 printw("Prepare your next move: "); |
| 727 clrtoeol(); |
730 clrtoeol(); |
| 728 refresh(); |
731 refresh(); |
| 729 |
732 |
| 739 return 1; |
742 return 1; |
| 740 } else if (strncmp(movestr, "taunt", MOVESTR_BUFLEN) == 0) { |
743 } else if (strncmp(movestr, "taunt", MOVESTR_BUFLEN) == 0) { |
| 741 resign_suggested = true; |
744 resign_suggested = true; |
| 742 net_send_code(opponent, NETCODE_TAUNT); |
745 net_send_code(opponent, NETCODE_TAUNT); |
| 743 } else if (strncmp(movestr, "remis", MOVESTR_BUFLEN) == 0) { |
746 } else if (strncmp(movestr, "remis", MOVESTR_BUFLEN) == 0) { |
| 744 remis_suggested = true; |
|
| 745 net_send_code(opponent, NETCODE_REMIS); |
747 net_send_code(opponent, NETCODE_REMIS); |
| |
748 if (remis_offered) { |
| |
749 gamestate->remis = true; |
| |
750 return 1; |
| |
751 } else { |
| |
752 remis_suggested = true; |
| |
753 } |
| 746 } else if (strncmp(movestr, "savepgn", MOVESTR_BUFLEN) == 0) { |
754 } else if (strncmp(movestr, "savepgn", MOVESTR_BUFLEN) == 0) { |
| 747 save_pgn(gamestate); |
755 save_pgn(gamestate); |
| 748 } else if (movestr[0] == 0) { |
756 } else if (movestr[0] == 0) { |
| 749 memset(gamestate->premove, 0, sizeof(gamestate->premove)); |
757 memset(gamestate->premove, 0, sizeof(gamestate->premove)); |
| 750 } else { |
758 } else { |
| 780 case NETCODE_REMIS: |
788 case NETCODE_REMIS: |
| 781 if (remis_suggested) { |
789 if (remis_suggested) { |
| 782 gamestate->remis = true; |
790 gamestate->remis = true; |
| 783 return 1; |
791 return 1; |
| 784 } else { |
792 } else { |
| 785 if (prompt_yesno( |
793 remis_offered = true; |
| 786 "\rYour opponent offers remis - do you accept")) { |
|
| 787 gamestate->remis = true; |
|
| 788 net_send_code(opponent, NETCODE_ACCEPT); |
|
| 789 return 1; |
|
| 790 } else { |
|
| 791 net_send_code(opponent, NETCODE_DECLINE); |
|
| 792 } |
|
| 793 } |
794 } |
| 794 break; |
795 break; |
| 795 /* validate "the game has ended" claims */ |
796 /* validate "the game has ended" claims */ |
| 796 case NETCODE_CHECKMATE: |
797 case NETCODE_CHECKMATE: |
| 797 return 1; /* no need to accept, they say they're toast, OK for us */ |
798 return 1; /* no need to accept, they say they're toast, OK for us */ |