src/main.c

changeset 188
bb967c8e51e9
parent 186
8230904458a7
child 189
444dfdf790b8
equal deleted inserted replaced
187:2834e444a956 188:bb967c8e51e9
665 switch (eval_result) { 665 switch (eval_result) {
666 case VALID_MOVE_SYNTAX: 666 case VALID_MOVE_SYNTAX:
667 NetMove nmove = hton_move(move); 667 NetMove nmove = hton_move(move);
668 net_send_data(opponent, NETCODE_MOVE, &nmove, NETMOVE_LEN); 668 net_send_data(opponent, NETCODE_MOVE, &nmove, NETMOVE_LEN);
669 code = net_recieve_code(opponent); 669 code = net_recieve_code(opponent);
670 /* we could validate the move's check/checkmate flag with
671 * the network response code, but we choose not to do it */
672 gamestate->checkmate = code == NETCODE_CHECKMATE;
673 gamestate->stalemate = code == NETCODE_STALEMATE;
674 if (code == NETCODE_DECLINE_MOVE) { 670 if (code == NETCODE_DECLINE_MOVE) {
675 uint8_t reason; 671 uint8_t reason;
676 net_recieve_data(opponent, &reason, 1); 672 net_recieve_data(opponent, &reason, 1);
677 eval_move_failed_msg(reason); 673 eval_move_failed_msg(reason);
678 } else if (code == NETCODE_ACCEPT 674 } else if (code == NETCODE_ACCEPT) {
679 || code == NETCODE_CHECK
680 || code == NETCODE_CHECKMATE
681 || code == NETCODE_STALEMATE
682 || code == NETCODE_NOMATERIAL) {
683 format_move(gamestate, &move); 675 format_move(gamestate, &move);
684 apply_move(gamestate, &move); 676 apply_move(gamestate, &move);
685 if (is_game_running(gamestate)) { 677 /* switch to waiting, even when the game ended.
686 return 0; 678 * we want to receive the "game end" code from the
687 } else { 679 * other party.
688 return 1; 680 */
689 } 681 return 0;
690 } else if (code == NETCODE_CONNLOST) { 682 } else if (code == NETCODE_CONNLOST) {
691 printw("Your opponent left the game."); 683 printw("Your opponent left the game.");
692 return 1; 684 return 1;
693 } else { 685 } else {
694 printw("Invalid network response."); 686 printw("Invalid network response.");
799 } else { 791 } else {
800 net_send_code(opponent, NETCODE_DECLINE); 792 net_send_code(opponent, NETCODE_DECLINE);
801 } 793 }
802 } 794 }
803 break; 795 break;
796 /* validate "the game has ended" claims */
804 case NETCODE_THREEFOLD: 797 case NETCODE_THREEFOLD:
805 /* validate the claim */ 798 case NETCODE_NOMATERIAL:
806 if (check_threefold_repetition(gamestate)) { 799 case NETCODE_STALEMATE:
800 case NETCODE_CHECKMATE:
801 if ((code == NETCODE_THREEFOLD && gamestate->threefold) ||
802 (code == NETCODE_NOMATERIAL && gamestate->nomaterial) ||
803 (code == NETCODE_STALEMATE && gamestate->stalemate) ||
804 (code == NETCODE_CHECKMATE && gamestate->checkmate)) {
807 /* auto-accept the claim */ 805 /* auto-accept the claim */
808 gamestate->threefold = true;
809 net_send_code(opponent, NETCODE_ACCEPT); 806 net_send_code(opponent, NETCODE_ACCEPT);
810 return 1; 807 return 1;
811 } else { 808 } else {
812 /* silently decline, do not add message to UI */ 809 /* silently decline, do not add message to UI */
813 net_send_code(opponent, NETCODE_DECLINE); 810 net_send_code(opponent, NETCODE_DECLINE);
819 Move move = ntoh_move(nmove); 816 Move move = ntoh_move(nmove);
820 code = validate_move(gamestate, &move); 817 code = validate_move(gamestate, &move);
821 if (code == VALID_MOVE_SEMANTICS) { 818 if (code == VALID_MOVE_SEMANTICS) {
822 format_move(gamestate, &move); 819 format_move(gamestate, &move);
823 apply_move(gamestate, &move); 820 apply_move(gamestate, &move);
821 net_send_code(opponent, NETCODE_ACCEPT);
822
823 /* send a code for ending the game, if required */
824 bool endgame = true;
824 if (gamestate->checkmate) { 825 if (gamestate->checkmate) {
825 net_send_code(opponent, NETCODE_CHECKMATE); 826 net_send_code(opponent, NETCODE_CHECKMATE);
826 return 1;
827 } else if (gamestate->stalemate) { 827 } else if (gamestate->stalemate) {
828 net_send_code(opponent, NETCODE_STALEMATE); 828 net_send_code(opponent, NETCODE_STALEMATE);
829 return 1;
830 } else if (gamestate->nomaterial) { 829 } else if (gamestate->nomaterial) {
831 net_send_code(opponent, NETCODE_NOMATERIAL); 830 net_send_code(opponent, NETCODE_NOMATERIAL);
832 return 1; 831 } else if (gamestate->threefold) {
833 } else if (move.check) { 832 /* Note: in our implementation it is an auto-draw claimed
834 net_send_code(opponent, NETCODE_CHECK); 833 * by the player confronted with the position. By standard
834 * chess rules, also the player who creates the position may
835 * claim the draw. But since we do it automatically, it
836 * makes no practical difference.
837 */
838 net_send_code(opponent, NETCODE_THREEFOLD);
835 } else { 839 } else {
836 net_send_code(opponent, NETCODE_ACCEPT); 840 endgame = false;
837 } 841 }
838 /* check for threefold repetition */ 842 /* await a response to the "end game" code */
839 /* Note: in our implementation it is an auto-draw claimed 843 if (endgame) {
840 * by the player confronted with the position. By standard
841 * chess rules, also the player who creates the position may
842 * claim the draw. But since we do it automatically, it makes
843 * no practical difference.
844 */
845 if (gamestate->threefold) {
846 /* send this as a new package (basically as next move) */
847 net_send_code(opponent, NETCODE_THREEFOLD);
848 /* the protocol supports declining the claim */
849 uint8_t resp = net_recieve_code(opponent); 844 uint8_t resp = net_recieve_code(opponent);
850 if (resp == NETCODE_ACCEPT) { 845 if (resp == NETCODE_ACCEPT) {
851 return 1; 846 return 1;
852 } else { 847 } else {
853 /* does not happen in our implementation */ 848 /* does not happen in our implementation */
854 // TODO: but what do we do if some other client declines? simply rage quit? 849 // TODO: but what do we do if some other client declines?
855 // should we instead rework the protocol that it's not possible to decline? 850 // currently, we simply continue playing,
851 // but that does not make any sense
856 return 0; 852 return 0;
857 } 853 }
858 } else {
859 return 0;
860 } 854 }
855 /* now it's our turn */
856 return 0;
861 } else { 857 } else {
862 net_send_data(opponent, NETCODE_DECLINE_MOVE, &code, 1); 858 net_send_data(opponent, NETCODE_DECLINE_MOVE, &code, 1);
863 } 859 }
864 break; 860 break;
865 } 861 }

mercurial