Tue, 08 Sep 2026 22:22:01 +0200
some cleanup and simplifications
| 0 | 1 | /* |
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. | |
| 3 | * | |
|
55
54ea19938d57
updated copyright and version info
Mike Becker <universe@uap-core.de>
parents:
52
diff
changeset
|
4 | * Copyright 2016 Mike Becker. All rights reserved. |
| 0 | 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without | |
| 7 | * modification, are permitted provided that the following conditions are met: | |
| 8 | * | |
| 9 | * 1. Redistributions of source code must retain the above copyright | |
| 10 | * notice, this list of conditions and the following disclaimer. | |
| 11 | * | |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 13 | * notice, this list of conditions and the following disclaimer in the | |
| 14 | * documentation and/or other materials provided with the distribution. | |
| 15 | * | |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
| 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
| 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 26 | * POSSIBILITY OF SUCH DAMAGE. | |
| 27 | * | |
| 28 | */ | |
| 29 | ||
|
92
84e0dec5db16
use port number instead of port string in network code
Mike Becker <universe@uap-core.de>
parents:
90
diff
changeset
|
30 | #define PROGRAM_VERSION "1.0 alpha" |
| 78 | 31 | |
|
208
e9c3d3e89465
try different include order to hopefully avoid problems with curses wanting to define bool
Mike Becker <universe@uap-core.de>
parents:
206
diff
changeset
|
32 | #include <curses.h> |
|
1
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
33 | #include <string.h> |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
34 | #include <time.h> |
| 69 | 35 | #include <locale.h> |
|
225
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
36 | #include <ctype.h> |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
37 | #include <sys/stat.h> |
| 129 | 38 | #include <signal.h> |
| 39 | #include <errno.h> | |
| 40 | #include <unistd.h> | |
|
190
c90386d55cb2
remove unnecessary fen.h include in main.c
Mike Becker <universe@uap-core.de>
parents:
189
diff
changeset
|
41 | #include <getopt.h> |
|
208
e9c3d3e89465
try different include order to hopefully avoid problems with curses wanting to define bool
Mike Becker <universe@uap-core.de>
parents:
206
diff
changeset
|
42 | |
|
e9c3d3e89465
try different include order to hopefully avoid problems with curses wanting to define bool
Mike Becker <universe@uap-core.de>
parents:
206
diff
changeset
|
43 | #include "chess/rules.h" |
|
e9c3d3e89465
try different include order to hopefully avoid problems with curses wanting to define bool
Mike Becker <universe@uap-core.de>
parents:
206
diff
changeset
|
44 | #include "chess/pgn.h" |
|
e9c3d3e89465
try different include order to hopefully avoid problems with curses wanting to define bool
Mike Becker <universe@uap-core.de>
parents:
206
diff
changeset
|
45 | #include "network.h" |
| 129 | 46 | |
| 47 | typedef struct { | |
| 48 | /** | |
| 49 | * Server host address. | |
| 50 | * TCP: server address or \c NULL when we are the server | |
| 51 | * Domain Socket: the path to the domain socket | |
| 52 | */ | |
| 53 | char* serverhost; | |
| 54 | char* continuepgn; | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
55 | unsigned short time; |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
56 | unsigned short addtime; |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
57 | unsigned short delay; |
| 129 | 58 | short port; |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
59 | uint8_t servercolor; |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
60 | bool timecontrol; |
| 129 | 61 | bool ishost; |
| 62 | bool usedomainsocket; | |
| 63 | bool singlemachine; | |
| 64 | bool disableflip; | |
| 65 | bool unicode; | |
| 66 | } Settings; | |
|
1
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
67 | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
68 | static Settings settings; |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
69 | |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
70 | static void init_settings(void) { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
71 | memset(&settings, 0, sizeof(settings)); |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
72 | settings.servercolor = WHITE; |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
73 | settings.port = 27015; |
|
197
9cbd4f09a22f
add option to select a specific curses implementation
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
74 | #ifndef DISABLE_UNICODE |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
75 | settings.unicode = !!setlocale(LC_CTYPE, "C.UTF-8"); |
|
197
9cbd4f09a22f
add option to select a specific curses implementation
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
76 | #endif |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
77 | } |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
78 | |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
79 | static void cleanup() { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
80 | endwin(); |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
81 | if (settings.usedomainsocket && settings.ishost) { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
82 | remove(settings.serverhost); |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
83 | } |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
84 | } |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
85 | |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
86 | static void settings_apply(GameState *gamestate) { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
87 | gamestate->info.servercolor = settings.servercolor; |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
88 | gamestate->info.timecontrol = settings.timecontrol; |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
89 | gamestate->info.time = settings.time; |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
90 | gamestate->info.addtime = settings.addtime; |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
91 | gamestate->info.delay = settings.delay; |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
92 | } |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
93 | |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
94 | static int get_settings(int argc, char **argv) { |
|
1
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
95 | char *valid; |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
96 | unsigned long int time, port; |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
97 | uint8_t timeunit = 60; |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
98 | size_t len; |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
99 | bool port_set = false; |
|
1
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
100 | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
101 | for (int opt ; (opt = getopt(argc, argv, "a:bc:d:Fhp:rsS:t:uUv")) != -1 ;) { |
|
1
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
102 | switch (opt) { |
|
47
d726e4b46c33
refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents:
46
diff
changeset
|
103 | case 'c': |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
104 | settings.continuepgn = optarg; |
|
47
d726e4b46c33
refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents:
46
diff
changeset
|
105 | break; |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
106 | case 'b': |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
107 | settings.servercolor = BLACK; |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
108 | break; |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
109 | case 'r': |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
110 | settings.servercolor = rand() & 1 ? WHITE : BLACK; |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
111 | break; |
|
26
e0a76ee1bb2b
introduced single machine mode
Mike Becker <universe@uap-core.de>
parents:
23
diff
changeset
|
112 | case 's': |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
113 | settings.singlemachine = true; |
|
90
395542d915d7
add option that disables board flip in solo games
Mike Becker <universe@uap-core.de>
parents:
89
diff
changeset
|
114 | break; |
|
395542d915d7
add option that disables board flip in solo games
Mike Becker <universe@uap-core.de>
parents:
89
diff
changeset
|
115 | case 'F': |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
116 | settings.disableflip = true; |
|
26
e0a76ee1bb2b
introduced single machine mode
Mike Becker <universe@uap-core.de>
parents:
23
diff
changeset
|
117 | break; |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
118 | case 'u': |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
119 | if (port_set) { |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
120 | fprintf(stderr, "Cannot use Unix domain sockets " |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
121 | "when a TCP port was specified.\n"); |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
122 | return 1; |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
123 | } |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
124 | settings.usedomainsocket = true; |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
125 | break; |
| 69 | 126 | case 'U': |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
127 | settings.unicode = false; |
| 69 | 128 | break; |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
129 | case 't': |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
130 | case 'a': |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
131 | case 'd': |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
132 | len = strlen(optarg); |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
133 | if (optarg[len-1] == 's') { |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
134 | optarg[len-1] = '\0'; |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
135 | timeunit = 1; |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
136 | } |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
137 | |
|
30
a285ee393860
experimental async input for single machine mode
Mike Becker <universe@uap-core.de>
parents:
29
diff
changeset
|
138 | if ((time = strtoul(optarg, &valid, 10))*timeunit > UINT16_MAX |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
139 | || *valid != '\0') { |
|
30
a285ee393860
experimental async input for single machine mode
Mike Becker <universe@uap-core.de>
parents:
29
diff
changeset
|
140 | fprintf(stderr, "Specified time is invalid (%s)" |
|
a285ee393860
experimental async input for single machine mode
Mike Becker <universe@uap-core.de>
parents:
29
diff
changeset
|
141 | "- Maximum: 65535 seconds (1092 minutes)\n", optarg); |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
142 | return 1; |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
143 | } else { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
144 | settings.timecontrol = 1; |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
145 | if (opt=='t') { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
146 | settings.time = timeunit * time; |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
147 | } else if (opt=='a') { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
148 | settings.addtime = time; |
|
1
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
149 | } else { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
150 | settings.delay = time; |
|
1
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
151 | } |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
152 | } |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
153 | break; |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
154 | case 'p': |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
155 | if (port_set) { |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
156 | fprintf(stderr, "Cannot use -p twice.\n"); |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
157 | return 1; |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
158 | } |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
159 | if (settings.usedomainsocket) { |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
160 | fprintf(stderr, "Cannot specify TCP port " |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
161 | "when using Unix domain sockets.\n"); |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
162 | return 1; |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
163 | } |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
164 | port = strtol(optarg, &valid, 10); |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
165 | if (port < 1025 || port > 65535 || *valid != '\0') { |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
166 | fprintf(stderr, |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
167 | "Invalid port number (%s) - choose a number between " |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
168 | "1025 and 65535\n", |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
169 | optarg); |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
170 | return 1; |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
171 | } else { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
172 | settings.port = (short) port; |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
173 | port_set = true; |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
174 | } |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
175 | break; |
| 52 | 176 | case 'v': |
| 177 | printf("terminal-chess : Version %s (Netcode Version %d)\n", | |
| 178 | PROGRAM_VERSION, NETCODE_VERSION); | |
| 179 | exit(0); | |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
180 | case 'h': |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
181 | case '?': |
| 52 | 182 | printf( |
| 183 | "Usage: terminal-chess [OPTION]... [HOST]\n" | |
| 184 | "Starts/joins a network chess game\n" | |
| 185 | "\nGeneral options\n" | |
| 186 | " -c <PGN file> Continue the specified game\n" | |
| 187 | " -h This help page\n" | |
| 188 | " -p TCP port to use (default: 27015)\n" | |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
189 | " -u Use Unix domain socket instead of TCP\n" |
|
197
9cbd4f09a22f
add option to select a specific curses implementation
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
190 | #ifndef DISABLE_UNICODE |
|
84
df47b7efb97d
disabling Unicode pieces is a general option
Mike Becker <universe@uap-core.de>
parents:
83
diff
changeset
|
191 | " -U Disables unicode pieces\n" |
|
197
9cbd4f09a22f
add option to select a specific curses implementation
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
192 | #endif |
| 75 | 193 | " -v Print version information and exits\n" |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
194 | "\nTime control (default: disabled)\n" |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
195 | " -t <time> Time limit in minutes (or seconds when used with 's' suffix)\n" |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
196 | " -a <time> The time in seconds to add after each move\n" |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
197 | " -d <time> A delay in seconds before the clock starts ticking each move\n" |
| 52 | 198 | "\nServer options\n" |
| 199 | " -b Server plays black pieces (default: white)\n" | |
| 200 | " -r Distribute color randomly\n" | |
|
90
395542d915d7
add option that disables board flip in solo games
Mike Becker <universe@uap-core.de>
parents:
89
diff
changeset
|
201 | "\nHot seat\n" |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
202 | " -s Play a hot seat game (network options are ignored)\n" |
|
90
395542d915d7
add option that disables board flip in solo games
Mike Becker <universe@uap-core.de>
parents:
89
diff
changeset
|
203 | " -F Do not automatically flip the board in hot seat games\n" |
| 52 | 204 | "\nNotes\n" |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
205 | "Use '-' for PGN files to read PGN data from standard input\n\n" |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
206 | "When playing over Unix domain socket, the HOST denotes the socket path.\n" |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
207 | "When the path doest not exist, a game is created. Otherwise, the program\n" |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
208 | "joins the existing game. When HOST is omitted, /tmp/chess.sock is used.\n" |
| 52 | 209 | ); |
| 210 | exit(0); | |
|
1
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
211 | } |
|
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
212 | } |
|
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
213 | |
|
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
214 | if (optind == argc - 1) { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
215 | settings.serverhost = argv[optind]; |
|
1
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
216 | } else if (optind < argc - 1) { |
|
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
217 | fprintf(stderr, "Too many arguments\n"); |
|
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
218 | return 1; |
|
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
219 | } |
|
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
220 | |
|
50
41017d0a72c5
added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
47
diff
changeset
|
221 | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
222 | if (settings.continuepgn) { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
223 | if (settings.serverhost) { |
|
50
41017d0a72c5
added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
47
diff
changeset
|
224 | fprintf(stderr, "Can't continue a game when joining a server.\n"); |
|
41017d0a72c5
added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
47
diff
changeset
|
225 | return 1; |
|
41017d0a72c5
added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
47
diff
changeset
|
226 | } |
|
41017d0a72c5
added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
47
diff
changeset
|
227 | } |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
228 | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
229 | if (settings.usedomainsocket) { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
230 | if (!settings.serverhost) { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
231 | settings.serverhost = "/tmp/chess.sock"; |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
232 | } |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
233 | struct stat st; |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
234 | if (stat(settings.serverhost, &st) == 0) { |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
235 | if (S_ISSOCK(st.st_mode)) { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
236 | settings.ishost = false; |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
237 | } else { |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
238 | fprintf(stderr, "%s is not a Unix domain socket.\n", |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
239 | settings.serverhost); |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
240 | return 1; |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
241 | } |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
242 | } else { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
243 | settings.ishost = true; |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
244 | } |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
245 | } else { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
246 | settings.ishost = !settings.serverhost; |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
247 | } |
|
50
41017d0a72c5
added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
47
diff
changeset
|
248 | |
|
1
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
249 | return 0; |
|
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
250 | } |
|
e5fbb8f9edbe
added (single) client / server architecture
Mike Becker <universe@uap-core.de>
parents:
0
diff
changeset
|
251 | |
|
225
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
252 | #ifdef USE_POSIX_CURSES |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
253 | #define COL_APP 0 |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
254 | #else |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
255 | #define COL_APP 1 |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
256 | #endif |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
257 | #define COL_BW 2 |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
258 | #define COL_WB 3 |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
259 | #define COL_BB 4 |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
260 | #define COL_WW 5 |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
261 | |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
262 | static void init_colorpairs(void) { |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
263 | #ifndef USE_POSIX_CURSES |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
264 | use_default_colors(); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
265 | init_pair(COL_APP, -1, -1); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
266 | #endif |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
267 | init_pair(COL_BW, COLOR_BLACK, COLOR_CYAN); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
268 | init_pair(COL_BB, COLOR_BLACK, COLOR_BLUE); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
269 | init_pair(COL_WB, COLOR_WHITE, COLOR_BLUE); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
270 | init_pair(COL_WW, COLOR_WHITE, COLOR_CYAN); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
271 | } |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
272 | |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
273 | static int prompt_yesno(const char *msg) { |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
274 | addstr(msg); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
275 | addstr(" (y/n)? "); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
276 | clrtoeol(); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
277 | refresh(); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
278 | noecho(); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
279 | int ch; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
280 | do { |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
281 | ch = getch(); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
282 | } while (ch != 'y' && ch != 'n'); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
283 | echo(); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
284 | |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
285 | return ch == 'y'; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
286 | } |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
287 | |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
288 | static int asyncgetnstr(char *str, size_t *pos, size_t len) { |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
289 | WINDOW* w = stdscr; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
290 | int y, x; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
291 | getyx(w, y, x); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
292 | mvwaddnstr(w, y, x, str, *pos); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
293 | wrefresh(w); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
294 | int c = wgetch(w); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
295 | |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
296 | if (c != ERR) { |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
297 | switch (c) { |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
298 | case KEY_DOWN: |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
299 | case '\n': |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
300 | str[*pos] = '\0'; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
301 | *pos = 0; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
302 | waddch(w,'\n'); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
303 | return 1; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
304 | case 127: /* ASCII DEL (important for macOS) */ |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
305 | case KEY_DC: /* DEL key (for other OS) */ |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
306 | case KEY_BACKSPACE: |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
307 | case KEY_LEFT: |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
308 | if ((*pos) > 0) { |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
309 | str[--(*pos)] = '\0'; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
310 | } |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
311 | break; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
312 | default: |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
313 | if (isprint(c) && *pos < len-1) { |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
314 | str[(*pos)++] = (char) c; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
315 | } |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
316 | } |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
317 | } |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
318 | |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
319 | return 0; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
320 | } |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
321 | |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
322 | static int input_getmaxy(void) { |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
323 | /* POSIX-curses-compliant wrapper for getmaxy() */ |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
324 | int x, y; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
325 | getmaxyx(stdscr, y, x); |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
326 | (void)x; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
327 | return y; |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
328 | } |
|
6e39f53127e9
some cleanup and simplifications
Mike Becker <universe@uap-core.de>
parents:
219
diff
changeset
|
329 | |
| 129 | 330 | static const uint8_t boardx = 4, boardy = 10; |
| 331 | static int inputy = 21; /* should be overridden on game startup */ | |
| 332 | ||
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
333 | static int timecontrol(GameState *gamestate) { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
334 | if (gamestate->info.timecontrol) { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
335 | uint16_t white = remaining_movetime(gamestate, WHITE); |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
336 | uint16_t black = remaining_movetime(gamestate, BLACK); |
| 129 | 337 | char clkstr[16]; |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
338 | bool always_hours = gamestate->info.time >= 3600; |
| 129 | 339 | print_clk(white, clkstr, always_hours); |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
340 | mvaddstr(boardy+4, boardx-1, "White time: "); |
|
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
341 | addstr(clkstr); |
| 129 | 342 | print_clk(black, clkstr, always_hours); |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
343 | mvaddstr(boardy+5, boardx-1, "Black time: "); |
|
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
344 | addstr(clkstr); |
| 129 | 345 | |
| 346 | if (white == 0) { | |
| 347 | move(inputy, 0); | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
348 | addstr("Time is over - Black wins!"); |
| 129 | 349 | clrtobot(); |
| 350 | refresh(); | |
| 351 | return 1; | |
| 352 | } | |
| 353 | if (black == 0) { | |
| 354 | move(inputy, 0); | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
355 | addstr("Time is over - White wins!"); |
| 129 | 356 | clrtobot(); |
| 357 | refresh(); | |
| 358 | return 1; | |
| 359 | } | |
| 360 | } | |
| 361 | ||
| 362 | return 0; | |
| 363 | } | |
| 364 | ||
| 194 | 365 | static void draw_board(GameState *gamestate, Color perspective) { |
|
157
07cbfc477b22
add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents:
154
diff
changeset
|
366 | if (gamestate->movecount == 0) { |
|
07cbfc477b22
add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents:
154
diff
changeset
|
367 | mvaddstr(0, 0, gamestate->fen_start); |
|
07cbfc477b22
add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents:
154
diff
changeset
|
368 | } else { |
|
07cbfc477b22
add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents:
154
diff
changeset
|
369 | mvaddstr(0, 0, gamestate->fen[gamestate->movecount - 1]); |
|
07cbfc477b22
add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents:
154
diff
changeset
|
370 | } |
| 129 | 371 | |
| 194 | 372 | for (Rank y = 0 ; y < 8 ; y++) { |
| 373 | for (File x = 0 ; x < 8 ; x++) { | |
|
195
27d02ccb0cef
flip File and Rank parameters into correct order
Mike Becker <universe@uap-core.de>
parents:
194
diff
changeset
|
374 | Piece piece = piece_at(gamestate, x, y); |
| 194 | 375 | Color col = piece_color(piece); |
| 376 | ||
| 129 | 377 | char piecestr[5]; |
| 378 | if (piece) { | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
379 | if (settings.unicode) { |
| 129 | 380 | char* uc = getpieceunicode(piece); |
| 381 | strncpy(piecestr, uc, 5); | |
| 382 | } else { | |
| 383 | piecestr[0] = (piece & PIECE_MASK) == PAWN | |
| 384 | ? 'P' : getpiecechr(piece); | |
| 385 | piecestr[1] = '\0'; | |
| 386 | } | |
| 387 | } else { | |
| 388 | piecestr[0] = ' '; | |
| 389 | piecestr[1] = '\0'; | |
| 390 | } | |
| 391 | ||
| 392 | bool boardblack = (y&1)==(x&1); | |
| 393 | attrset((col==WHITE ? A_BOLD : A_DIM)| | |
| 394 | COLOR_PAIR(col == WHITE ? | |
| 395 | (boardblack ? COL_WB : COL_WW) : | |
| 396 | (boardblack ? COL_BB : COL_BW) | |
| 397 | ) | |
| 398 | ); | |
| 399 | ||
| 400 | int cy = perspective == WHITE ? boardy-y : boardy-7+y; | |
| 401 | int cx = perspective == WHITE ? boardx+x*3 : boardx+21-x*3; | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
402 | mvaddch(cy, cx, ' '); |
|
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
403 | addstr(piecestr); |
|
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
404 | addch(' '); |
| 129 | 405 | } |
| 406 | } | |
| 407 | ||
| 408 | attrset(A_NORMAL); | |
| 409 | for (uint8_t i = 0 ; i < 8 ; i++) { | |
| 410 | int x = perspective == WHITE ? boardx+i*3+1 : boardx+22-i*3; | |
| 411 | int y = perspective == WHITE ? boardy-i : boardy-7+i; | |
| 412 | mvaddch(boardy+1, x, 'a'+i); | |
| 413 | mvaddch(y, boardx-2, '1'+i); | |
| 414 | } | |
| 415 | ||
| 416 | /* move log */ | |
| 417 | uint8_t logy = 2; | |
| 418 | const uint8_t logx = boardx + 28; | |
| 419 | move(logy, logx); | |
| 420 | ||
| 421 | /* count full moves */ | |
| 422 | unsigned int logi = 0; | |
| 423 | ||
| 424 | /* wrap log after 45 moves */ | |
| 425 | while (gamestate->movecount/6-logi/3 >= 15) { | |
| 426 | logi++; | |
| 427 | } | |
| 428 | ||
| 429 | for (unsigned mi = logi*2 ; mi < gamestate->movecount ; mi++) { | |
| 430 | bool iswhite = mi % 2 == 0; | |
| 431 | if (iswhite) { | |
| 432 | logi++; | |
|
219
24b866230dd4
identify all and fix some occurrences where the new move_start offset matters
Mike Becker <universe@uap-core.de>
parents:
212
diff
changeset
|
433 | printw("%d. ", logi); // TODO: add move_start offset |
| 129 | 434 | } |
| 435 | ||
| 436 | addstr(gamestate->moves[mi].string); | |
| 437 | if (!iswhite && logi%3 == 0) { | |
| 438 | move(++logy, logx); | |
| 439 | } else { | |
| 440 | addch(' '); | |
| 441 | } | |
| 442 | } | |
| 443 | } | |
| 444 | ||
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
445 | static void eval_move_failed_msg(int code) { |
| 129 | 446 | switch (code) { |
| 447 | case AMBIGUOUS_MOVE: | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
448 | addstr("Ambiguous move - please specify the piece to move."); |
| 129 | 449 | break; |
|
154
5336e985bd69
rename INVALID_POSITION to PIECE_NOT_FOUND
Mike Becker <universe@uap-core.de>
parents:
150
diff
changeset
|
450 | case PIECE_NOT_FOUND: |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
451 | addstr("No piece can be moved this way."); |
| 129 | 452 | break; |
| 453 | case NEED_PROMOTION: | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
454 | addstr("You need to promote the pawn (append \"=Q\" e.g.)!"); |
| 129 | 455 | break; |
| 456 | case KING_IN_CHECK: | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
457 | addstr("Your king is in check!"); |
| 129 | 458 | break; |
| 459 | case PIECE_PINNED: | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
460 | addstr("This piece is pinned!"); |
| 129 | 461 | break; |
| 462 | case INVALID_MOVE_SYNTAX: | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
463 | addstr("Can't interpret move - please use algebraic notation."); |
| 129 | 464 | break; |
| 465 | case RULES_VIOLATED: | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
466 | addstr("Move does not comply with chess rules."); |
| 129 | 467 | break; |
| 468 | case KING_MOVES_INTO_CHECK: | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
469 | addstr("Can't move the king into a check position."); |
| 129 | 470 | break; |
|
163
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
157
diff
changeset
|
471 | case MISSING_CHECK: |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
472 | addstr("Move does not indicate check."); |
|
163
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
157
diff
changeset
|
473 | break; |
|
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
157
diff
changeset
|
474 | case MISSING_CHECKMATE: |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
475 | addstr("Move does not indicate checkmate."); |
|
163
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
157
diff
changeset
|
476 | break; |
|
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
157
diff
changeset
|
477 | case INVALID_CHECK: |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
478 | addstr("Move incorrectly indicates check."); |
|
163
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
157
diff
changeset
|
479 | break; |
|
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
157
diff
changeset
|
480 | case INVALID_CHECKMATE: |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
481 | addstr("Move incorrectly indicates checkmate."); |
|
163
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
157
diff
changeset
|
482 | break; |
| 129 | 483 | default: |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
484 | addstr("Unknown move parser error."); |
| 129 | 485 | } |
| 486 | } | |
| 487 | ||
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
488 | static void save_pgn(GameState *gamestate) { |
|
202
6960625e62e0
fix getmaxy() not being available in POSIX curses
Mike Becker <universe@uap-core.de>
parents:
199
diff
changeset
|
489 | int y; |
|
6960625e62e0
fix getmaxy() not being available in POSIX curses
Mike Becker <universe@uap-core.de>
parents:
199
diff
changeset
|
490 | { |
|
6960625e62e0
fix getmaxy() not being available in POSIX curses
Mike Becker <universe@uap-core.de>
parents:
199
diff
changeset
|
491 | int x; |
|
6960625e62e0
fix getmaxy() not being available in POSIX curses
Mike Becker <universe@uap-core.de>
parents:
199
diff
changeset
|
492 | getyx(stdscr, y, x); |
|
6960625e62e0
fix getmaxy() not being available in POSIX curses
Mike Becker <universe@uap-core.de>
parents:
199
diff
changeset
|
493 | (void)x; /* we want to be POSIX curses compliant */ |
|
6960625e62e0
fix getmaxy() not being available in POSIX curses
Mike Becker <universe@uap-core.de>
parents:
199
diff
changeset
|
494 | } |
| 129 | 495 | |
| 496 | /* ask for player names */ | |
| 497 | { | |
| 498 | char pname[PLAYER_NAME_BUFLEN]; | |
| 499 | printw("\rWhite's name (%s): ", pgn_player_name(gamestate, WHITE)); | |
| 500 | clrtoeol(); | |
| 501 | if (getnstr(pname, PLAYER_NAME_BUFLEN) == OK && pname[0] != '\0') { | |
| 502 | strncpy(gamestate->wname, pname, PLAYER_NAME_BUFLEN); | |
| 503 | } | |
| 504 | move(y, 0); | |
| 505 | printw("\rBlack's name (%s): ", pgn_player_name(gamestate, BLACK)); | |
| 506 | clrtoeol(); | |
| 507 | if (getnstr(pname, PLAYER_NAME_BUFLEN) == OK && pname[0] != '\0') { | |
| 508 | strncpy(gamestate->bname, pname, PLAYER_NAME_BUFLEN); | |
| 509 | } | |
| 510 | move(y, 0); | |
| 511 | } | |
| 512 | ||
| 513 | bool export_comments = prompt_yesno("Export with comments"); | |
| 514 | ||
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
515 | addstr("\rFilename: "); |
| 129 | 516 | clrtoeol(); |
| 517 | ||
| 518 | char filename[64]; | |
| 519 | if (getnstr(filename, 64) == OK && filename[0] != '\0') { | |
| 520 | move(y, 0); | |
| 521 | FILE *file = fopen(filename, "w"); | |
| 522 | if (file) { | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
523 | write_pgn(file, gamestate, export_comments); |
| 129 | 524 | fclose(file); |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
525 | addstr("File saved."); |
| 129 | 526 | } else { |
| 527 | printw("Can't write to file (%s).", strerror(errno)); | |
| 528 | } | |
| 529 | clrtoeol(); | |
| 530 | } | |
| 531 | } | |
| 532 | ||
| 533 | #define MOVESTR_BUFLEN 10 | |
| 194 | 534 | static int domove_singlemachine(GameState *gamestate, Color curcolor) { |
| 129 | 535 | size_t bufpos = 0; |
| 536 | char movestr[MOVESTR_BUFLEN]; | |
| 537 | ||
| 538 | flushinp(); | |
| 539 | while (1) { | |
| 540 | const char *curcolorstr = curcolor == WHITE ? "White" : "Black"; | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
541 | if (timecontrol(gamestate)) { |
| 129 | 542 | return 1; |
| 543 | } | |
| 544 | move(inputy, 0); | |
| 545 | printw( | |
| 546 | "Use chess notation to enter your move.\n" | |
| 547 | "Or use a command: remis, resign, savepgn\n\n" | |
| 548 | "%s to move: ", curcolorstr); | |
| 549 | clrtoeol(); | |
| 550 | ||
| 551 | if (asyncgetnstr(movestr, &bufpos, MOVESTR_BUFLEN)) { | |
| 552 | if (strncmp(movestr, "resign", MOVESTR_BUFLEN) == 0) { | |
| 553 | if (curcolor == WHITE) { | |
| 554 | gamestate->wresign = true; | |
| 555 | } else { | |
| 556 | gamestate->bresign = true; | |
| 557 | } | |
| 558 | return 1; | |
| 559 | } else if (strncmp(movestr, "remis", MOVESTR_BUFLEN) == 0) { | |
| 560 | gamestate->remis = true; | |
| 561 | return 1; | |
| 562 | } else if (strncmp(movestr, "savepgn", MOVESTR_BUFLEN) == 0) { | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
563 | save_pgn(gamestate); |
| 129 | 564 | } else if (movestr[0] == 0) { |
| 565 | /* ignore empty move strings and ask again */ | |
| 566 | } else { | |
| 567 | Move move; | |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
568 | int result = eval_move(gamestate, |
|
163
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
157
diff
changeset
|
569 | movestr, curcolor, &move); |
| 129 | 570 | if (result == VALID_MOVE_SYNTAX) { |
| 571 | result = validate_move(gamestate, &move); | |
| 572 | if (result == VALID_MOVE_SEMANTICS) { | |
|
186
8230904458a7
fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents:
185
diff
changeset
|
573 | format_move(gamestate, &move); |
| 129 | 574 | apply_move(gamestate, &move); |
|
179
5ef724e21702
implement draw due to insufficient material
Mike Becker <universe@uap-core.de>
parents:
176
diff
changeset
|
575 | if (is_game_running(gamestate)) { |
|
5ef724e21702
implement draw due to insufficient material
Mike Becker <universe@uap-core.de>
parents:
176
diff
changeset
|
576 | return 0; |
|
5ef724e21702
implement draw due to insufficient material
Mike Becker <universe@uap-core.de>
parents:
176
diff
changeset
|
577 | } else { |
| 129 | 578 | return 1; |
| 579 | } | |
| 580 | } else { | |
| 581 | eval_move_failed_msg(result); | |
| 582 | } | |
| 583 | } else { | |
| 584 | eval_move_failed_msg(result); | |
| 585 | } | |
| 586 | clrtoeol(); | |
| 587 | } | |
| 588 | } | |
| 589 | } | |
| 590 | } | |
| 591 | ||
|
186
8230904458a7
fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents:
185
diff
changeset
|
592 | #define NETMOVE_LEN 16 |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
593 | #define NETGI_LEN 8 |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
594 | |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
595 | static NetGameInfo hton_gi(GameInfo gi) { |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
596 | return (NetGameInfo) { |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
597 | .servercolor = gi.servercolor, |
|
186
8230904458a7
fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents:
185
diff
changeset
|
598 | .timecontrol = gi.timecontrol, |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
599 | .time = net_htons(gi.time), |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
600 | .addtime = net_htons(gi.addtime), |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
601 | .delay = net_htons(gi.delay) |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
602 | }; |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
603 | } |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
604 | |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
605 | static GameInfo ntoh_gi(NetGameInfo gi) { |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
606 | return (GameInfo) { |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
607 | .servercolor = gi.servercolor, |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
608 | .timecontrol = gi.timecontrol, |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
609 | .time = net_ntohs(gi.time), |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
610 | .addtime = net_ntohs(gi.addtime), |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
611 | .delay = net_ntohs(gi.delay) |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
612 | }; |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
613 | } |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
614 | |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
615 | static NetMove hton_move(Move move) { |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
616 | return (NetMove) { |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
617 | .mtime_sec = net_htonl(move.movetime / 1000000ull), |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
618 | .mtime_usec = net_htonl(move.movetime % 1000000ull), |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
619 | .piece = move.piece, |
| 194 | 620 | .fromfile = move.fromfile, .fromrank = move.fromrank, |
| 621 | .tofile = move.tofile, .torank = move.torank, | |
|
186
8230904458a7
fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents:
185
diff
changeset
|
622 | .capture = move.capture, |
|
8230904458a7
fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents:
185
diff
changeset
|
623 | .check_or_mate = move.checkmate + move.check, |
|
8230904458a7
fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents:
185
diff
changeset
|
624 | .promotion = move.promotion, |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
625 | }; |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
626 | } |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
627 | |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
628 | static Move ntoh_move(NetMove move) { |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
629 | return (Move) { |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
630 | .string = {0}, /* calculated before applying the move */ |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
631 | .timestamp = {0}, /* planned to be removed */ |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
632 | .movetime = (uint64_t)net_ntohl(move.mtime_sec) |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
633 | * 1000000ull + net_ntohl(move.mtime_usec), |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
634 | .piece = move.piece, |
| 194 | 635 | .fromfile = move.fromfile, .fromrank = move.fromrank, |
| 636 | .tofile = move.tofile, .torank = move.torank, | |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
637 | .promotion = move.promotion, |
|
186
8230904458a7
fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents:
185
diff
changeset
|
638 | .check = move.check_or_mate, |
|
8230904458a7
fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents:
185
diff
changeset
|
639 | .checkmate = move.check_or_mate >> 1, |
|
8230904458a7
fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents:
185
diff
changeset
|
640 | .capture = move.capture |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
641 | }; |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
642 | } |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
643 | |
| 194 | 644 | static int sendmove(GameState *gamestate, int opponent, Color mycolor) { |
| 129 | 645 | |
| 646 | size_t bufpos = 0; | |
| 647 | char movestr[MOVESTR_BUFLEN]; | |
|
192
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
648 | bool remis_offered = false; |
| 129 | 649 | bool remis_rejected = false; |
| 650 | bool remis_suggested = false; | |
| 651 | bool resign_suggested = false; | |
| 652 | bool use_premove = false; | |
| 653 | uint8_t code; | |
| 654 | ||
| 655 | if (*gamestate->premove) { | |
| 656 | use_premove = true; | |
| 657 | const unsigned mlen = sizeof(gamestate->premove); | |
| 658 | strncpy(movestr, gamestate->premove, mlen); | |
| 659 | movestr[mlen] = '\0'; | |
| 660 | memset(gamestate->premove, 0, mlen); | |
| 661 | } | |
| 662 | ||
| 663 | flushinp(); | |
| 664 | while (1) { | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
665 | if (timecontrol(gamestate)) { |
| 129 | 666 | net_send_code(opponent, NETCODE_TIMEOVER); |
| 667 | return 1; | |
| 668 | } | |
| 669 | ||
| 670 | move(inputy, 0); | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
671 | addstr("Use chess notation to enter your move.\n"); |
| 129 | 672 | if (resign_suggested) { |
| 673 | if (remis_suggested) { | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
674 | addstr("The opponent asks you to resign or accept remis. \n\n"); |
| 129 | 675 | } else { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
676 | addstr("The opponent asks you to resign. \n\n"); |
| 129 | 677 | } |
| 678 | } else if (remis_suggested) { | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
679 | addstr("The opponent offers remis. Type remis to accept. \n\n"); |
| 129 | 680 | } else if (remis_rejected) { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
681 | addstr("Remis offer rejected. \n\n"); |
|
192
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
682 | } else if (remis_offered) { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
683 | addstr("Remis offer sent. \n\n"); |
| 129 | 684 | } else { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
685 | addstr("Or use a command: remis, resign, savepgn \n\n"); |
| 129 | 686 | } |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
687 | addstr("Type your move: "); |
| 129 | 688 | clrtoeol(); |
| 689 | ||
| 690 | /* check if the opponent sent us something */ | |
| 691 | code = net_recieve_code_async(opponent); | |
| 692 | switch (code) { | |
| 693 | case NETCODE_REMIS: | |
|
192
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
694 | if (remis_offered) { |
|
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
695 | gamestate->remis = true; |
|
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
696 | return 1; |
|
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
697 | } |
| 129 | 698 | remis_suggested = true; |
| 699 | break; | |
| 700 | case NETCODE_TAUNT: | |
| 701 | resign_suggested = true; | |
| 702 | break; | |
| 703 | case NETCODE_RESIGN: | |
| 704 | if (mycolor == WHITE) { | |
| 705 | gamestate->bresign = true; | |
| 706 | } else { | |
| 707 | gamestate->wresign = true; | |
| 708 | } | |
| 709 | return 1; | |
| 710 | case NETCODE_CONNLOST: | |
| 711 | gamestate->ragequit = true; | |
| 712 | return 1; | |
| 713 | case NETCODE_ERROR: | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
714 | addstr("\rCannot perform asynchronous network IO"); |
| 129 | 715 | cbreak(); getch(); |
| 716 | exit(EXIT_FAILURE); | |
| 717 | case NETCODE_AGAIN: | |
| 718 | /* try again */ | |
| 719 | break; | |
| 720 | default: | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
721 | addstr("\nThe opponent sent an invalid network pacakge."); |
| 129 | 722 | } |
| 723 | ||
| 724 | /* read move */ | |
| 725 | if (use_premove || asyncgetnstr(movestr, &bufpos, MOVESTR_BUFLEN)) { | |
| 726 | bool was_premove = use_premove; | |
| 727 | use_premove = false; | |
| 728 | if (strncmp(movestr, "resign", MOVESTR_BUFLEN) == 0) { | |
| 729 | if (mycolor == WHITE) { | |
| 730 | gamestate->wresign = true; | |
| 731 | } else { | |
| 732 | gamestate->bresign = true; | |
| 733 | } | |
| 734 | net_send_code(opponent, NETCODE_RESIGN); | |
| 735 | return 1; | |
| 736 | } else if (strncmp(movestr, "savepgn", MOVESTR_BUFLEN) == 0) { | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
737 | save_pgn(gamestate); |
| 129 | 738 | } else if (strncmp(movestr, "remis", MOVESTR_BUFLEN) == 0) { |
| 739 | if (remis_suggested) { | |
| 740 | net_send_code(opponent, NETCODE_REMIS); | |
| 741 | gamestate->remis = true; | |
| 742 | return 1; | |
| 743 | } if (!remis_rejected) { | |
| 744 | net_send_code(opponent, NETCODE_REMIS); | |
|
192
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
745 | remis_offered = true; |
| 129 | 746 | } |
|
192
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
747 | /* prevent spamming the remis message */ |
| 129 | 748 | } else if (movestr[0] == 0) { |
| 749 | /* ignore empty move strings and ask again */ | |
| 750 | } else { | |
| 751 | Move move; | |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
752 | int eval_result = eval_move(gamestate, |
|
163
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
157
diff
changeset
|
753 | movestr, mycolor, &move); |
|
199
3d4d361ebb80
fix label before declaration
Mike Becker <universe@uap-core.de>
parents:
197
diff
changeset
|
754 | if (eval_result == VALID_MOVE_SYNTAX) { |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
755 | NetMove nmove = hton_move(move); |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
756 | net_send_data(opponent, NETCODE_MOVE, &nmove, NETMOVE_LEN); |
| 129 | 757 | code = net_recieve_code(opponent); |
|
176
ef8c39362342
split DECLINE message into DECLINE and DECLINE_MOVE
Mike Becker <universe@uap-core.de>
parents:
175
diff
changeset
|
758 | if (code == NETCODE_DECLINE_MOVE) { |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
759 | uint8_t reason; |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
760 | net_recieve_data(opponent, &reason, 1); |
| 129 | 761 | eval_move_failed_msg(reason); |
|
189
444dfdf790b8
rework network message codes + add NETCODE_ACCEPT_MOVE
Mike Becker <universe@uap-core.de>
parents:
188
diff
changeset
|
762 | } else if (code == NETCODE_ACCEPT_MOVE) { |
|
186
8230904458a7
fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents:
185
diff
changeset
|
763 | format_move(gamestate, &move); |
| 129 | 764 | apply_move(gamestate, &move); |
|
188
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
765 | /* switch to waiting, even when the game ended. |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
766 | * we want to receive the "game end" code from the |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
767 | * other party. |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
768 | */ |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
769 | return 0; |
| 129 | 770 | } else if (code == NETCODE_CONNLOST) { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
771 | addstr("Your opponent left the game."); |
| 129 | 772 | return 1; |
| 773 | } else { | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
774 | addstr("Invalid network response."); |
| 129 | 775 | } |
|
199
3d4d361ebb80
fix label before declaration
Mike Becker <universe@uap-core.de>
parents:
197
diff
changeset
|
776 | } else { |
| 129 | 777 | if (was_premove) { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
778 | addstr("\nThe prepared move could not be executed."); |
| 129 | 779 | } else { |
| 780 | eval_move_failed_msg(eval_result); | |
| 781 | } | |
| 782 | } | |
| 783 | clrtoeol(); | |
| 784 | } | |
| 785 | } | |
| 786 | } | |
| 787 | } | |
| 788 | ||
| 194 | 789 | static int recvmove(GameState *gamestate, int opponent, Color mycolor) { |
| 129 | 790 | memset(gamestate->premove, 0, sizeof(gamestate->premove)); |
| 791 | ||
| 792 | size_t bufpos = 0; | |
| 793 | char movestr[MOVESTR_BUFLEN]; | |
|
192
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
794 | bool remis_suggested = false, remis_offered = false; |
|
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
795 | bool resign_suggested = false; |
| 129 | 796 | while (1) { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
797 | timecontrol(gamestate); |
| 129 | 798 | |
| 799 | move(inputy, 0); | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
800 | addstr("Waiting for opponent. Use chess notation to prepare a move.\n"); |
| 129 | 801 | if (*gamestate->premove) { |
|
192
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
802 | printw("Current pre-move: %s \n", |
| 129 | 803 | gamestate->premove); |
| 804 | } else if (remis_suggested && !resign_suggested) { | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
805 | addstr("Suggested remis. \n"); |
| 129 | 806 | } else if (resign_suggested) { |
| 807 | if (remis_suggested) { | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
808 | addstr("Suggested to resign or at least to accept remis. \n"); |
| 129 | 809 | } else { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
810 | addstr("Suggested to resign. \n"); |
| 129 | 811 | } |
| 812 | } else { | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
813 | addstr("Or use a command: remis, resign, taunt, savepgn \n"); |
|
192
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
814 | } |
|
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
815 | if (remis_offered) { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
816 | addstr("Opponent offered remis. Type 'remis' to accept.\n"); |
|
192
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
817 | } else { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
818 | addch('\n'); |
| 129 | 819 | } |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
820 | addstr("Prepare your next move: "); |
| 129 | 821 | clrtoeol(); |
| 822 | refresh(); | |
| 823 | ||
| 824 | /* allow the player to prepare a move */ | |
| 825 | if (asyncgetnstr(movestr, &bufpos, MOVESTR_BUFLEN)) { | |
| 826 | if (strncmp(movestr, "resign", MOVESTR_BUFLEN) == 0) { | |
| 827 | if (mycolor == WHITE) { | |
| 828 | gamestate->wresign = true; | |
| 829 | } else { | |
| 830 | gamestate->bresign = true; | |
| 831 | } | |
| 832 | net_send_code(opponent, NETCODE_RESIGN); | |
| 833 | return 1; | |
| 834 | } else if (strncmp(movestr, "taunt", MOVESTR_BUFLEN) == 0) { | |
| 835 | resign_suggested = true; | |
| 836 | net_send_code(opponent, NETCODE_TAUNT); | |
| 837 | } else if (strncmp(movestr, "remis", MOVESTR_BUFLEN) == 0) { | |
| 838 | net_send_code(opponent, NETCODE_REMIS); | |
|
192
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
839 | if (remis_offered) { |
|
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
840 | gamestate->remis = true; |
|
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
841 | return 1; |
|
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
842 | } else { |
|
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
843 | remis_suggested = true; |
|
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
844 | } |
| 129 | 845 | } else if (strncmp(movestr, "savepgn", MOVESTR_BUFLEN) == 0) { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
846 | save_pgn(gamestate); |
| 129 | 847 | } else if (movestr[0] == 0) { |
| 848 | memset(gamestate->premove, 0, sizeof(gamestate->premove)); | |
| 849 | } else { | |
| 850 | int res = check_move(movestr, mycolor); | |
| 851 | if (res == VALID_MOVE_SYNTAX) { | |
| 852 | strncpy(gamestate->premove, movestr, 8); | |
| 853 | memset(movestr, 0, MOVESTR_BUFLEN); | |
| 854 | bufpos = 0; | |
| 855 | clrtobot(); | |
| 856 | } else { | |
| 857 | eval_move_failed_msg(res); | |
| 858 | } | |
| 859 | } | |
| 860 | } | |
| 861 | ||
| 862 | /* read opponent's move */ | |
| 863 | uint8_t code = net_recieve_code_async(opponent); | |
| 864 | switch (code) { | |
| 865 | case NETCODE_TIMEOVER: | |
| 866 | /* redraw the time control */ | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
867 | timecontrol(gamestate); |
| 129 | 868 | return 1; |
| 869 | case NETCODE_RESIGN: | |
| 870 | if (mycolor == WHITE) { | |
| 871 | gamestate->bresign = true; | |
| 872 | } else { | |
| 873 | gamestate->wresign = true; | |
| 874 | } | |
| 875 | return 1; | |
| 876 | case NETCODE_CONNLOST: | |
| 877 | gamestate->ragequit = true; | |
| 878 | return 1; | |
| 879 | case NETCODE_REMIS: | |
| 880 | if (remis_suggested) { | |
| 881 | gamestate->remis = true; | |
| 882 | return 1; | |
| 883 | } else { | |
|
192
e57e2874fb2a
fix how agreeing on a draw works
Mike Becker <universe@uap-core.de>
parents:
191
diff
changeset
|
884 | remis_offered = true; |
| 129 | 885 | } |
| 886 | break; | |
|
188
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
887 | /* validate "the game has ended" claims */ |
|
191
6da16865a270
complete documentation of the network protocol
Mike Becker <universe@uap-core.de>
parents:
190
diff
changeset
|
888 | case NETCODE_CHECKMATE: |
|
6da16865a270
complete documentation of the network protocol
Mike Becker <universe@uap-core.de>
parents:
190
diff
changeset
|
889 | return 1; /* no need to accept, they say they're toast, OK for us */ |
|
131
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
890 | case NETCODE_THREEFOLD: |
|
188
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
891 | case NETCODE_NOMATERIAL: |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
892 | case NETCODE_STALEMATE: |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
893 | if ((code == NETCODE_THREEFOLD && gamestate->threefold) || |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
894 | (code == NETCODE_NOMATERIAL && gamestate->nomaterial) || |
|
191
6da16865a270
complete documentation of the network protocol
Mike Becker <universe@uap-core.de>
parents:
190
diff
changeset
|
895 | (code == NETCODE_STALEMATE && gamestate->stalemate)) { |
|
131
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
896 | /* auto-accept the claim */ |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
897 | net_send_code(opponent, NETCODE_ACCEPT); |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
898 | return 1; |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
899 | } else { |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
900 | /* silently decline, do not add message to UI */ |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
901 | net_send_code(opponent, NETCODE_DECLINE); |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
902 | } |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
903 | break; |
| 129 | 904 | case NETCODE_MOVE: { |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
905 | NetMove nmove; |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
906 | net_recieve_data(opponent, &nmove, NETMOVE_LEN); |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
907 | Move move = ntoh_move(nmove); |
| 129 | 908 | code = validate_move(gamestate, &move); |
| 909 | if (code == VALID_MOVE_SEMANTICS) { | |
|
186
8230904458a7
fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents:
185
diff
changeset
|
910 | format_move(gamestate, &move); |
| 129 | 911 | apply_move(gamestate, &move); |
|
189
444dfdf790b8
rework network message codes + add NETCODE_ACCEPT_MOVE
Mike Becker <universe@uap-core.de>
parents:
188
diff
changeset
|
912 | net_send_code(opponent, NETCODE_ACCEPT_MOVE); |
|
188
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
913 | |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
914 | /* send a code for ending the game, if required */ |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
915 | bool endgame = true; |
| 129 | 916 | if (gamestate->checkmate) { |
| 917 | net_send_code(opponent, NETCODE_CHECKMATE); | |
|
191
6da16865a270
complete documentation of the network protocol
Mike Becker <universe@uap-core.de>
parents:
190
diff
changeset
|
918 | /* checkmate does not need to be accepted */ |
|
6da16865a270
complete documentation of the network protocol
Mike Becker <universe@uap-core.de>
parents:
190
diff
changeset
|
919 | return 1; |
| 129 | 920 | } else if (gamestate->stalemate) { |
| 921 | net_send_code(opponent, NETCODE_STALEMATE); | |
|
179
5ef724e21702
implement draw due to insufficient material
Mike Becker <universe@uap-core.de>
parents:
176
diff
changeset
|
922 | } else if (gamestate->nomaterial) { |
|
5ef724e21702
implement draw due to insufficient material
Mike Becker <universe@uap-core.de>
parents:
176
diff
changeset
|
923 | net_send_code(opponent, NETCODE_NOMATERIAL); |
|
188
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
924 | } else if (gamestate->threefold) { |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
925 | /* Note: in our implementation it is an auto-draw claimed |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
926 | * by the player confronted with the position. By standard |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
927 | * chess rules, also the player who creates the position may |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
928 | * claim the draw. But since we do it automatically, it |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
929 | * makes no practical difference. |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
930 | */ |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
931 | net_send_code(opponent, NETCODE_THREEFOLD); |
| 129 | 932 | } else { |
|
188
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
933 | endgame = false; |
| 129 | 934 | } |
|
188
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
935 | /* await a response to the "end game" code */ |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
936 | if (endgame) { |
|
131
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
937 | uint8_t resp = net_recieve_code(opponent); |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
938 | if (resp == NETCODE_ACCEPT) { |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
939 | return 1; |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
940 | } else { |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
941 | /* does not happen in our implementation */ |
|
188
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
942 | // TODO: but what do we do if some other client declines? |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
943 | // currently, we simply continue playing, |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
944 | // but that does not make any sense |
|
131
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
945 | return 0; |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
946 | } |
|
c33567d61ba7
prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents:
130
diff
changeset
|
947 | } |
|
188
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
948 | /* now it's our turn */ |
|
bb967c8e51e9
change how a game is ended in multiplayer
Mike Becker <universe@uap-core.de>
parents:
186
diff
changeset
|
949 | return 0; |
| 129 | 950 | } else { |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
951 | net_send_data(opponent, NETCODE_DECLINE_MOVE, &code, 1); |
| 129 | 952 | } |
| 953 | break; | |
| 954 | } | |
| 955 | case NETCODE_ERROR: | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
956 | addstr("\rCannot perform asynchronous network IO"); |
| 129 | 957 | cbreak(); getch(); |
| 958 | exit(EXIT_FAILURE); | |
| 959 | case NETCODE_AGAIN: | |
| 960 | /* try again */ | |
| 961 | break; | |
| 962 | default: | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
963 | addstr("\nInvalid network request."); |
| 129 | 964 | } |
| 965 | } | |
| 966 | } | |
| 967 | ||
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
968 | static void game_review(GameState *gamestate) { |
| 129 | 969 | const unsigned page_moves = 10; |
| 970 | GameState viewedstate = {0}; | |
| 971 | unsigned viewedmove = gamestate->movecount; | |
| 972 | bool redraw = true; | |
| 973 | ||
| 974 | noecho(); | |
| 975 | int c; | |
| 976 | do { | |
| 977 | if (redraw) { | |
| 978 | gamestate_cleanup(&viewedstate); | |
| 979 | gamestate_at_move(gamestate, viewedmove, &viewedstate); | |
| 980 | ||
| 981 | erase(); /* don't use clear() to avoid flickering */ | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
982 | draw_board(&viewedstate, WHITE); |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
983 | timecontrol(&viewedstate); |
| 129 | 984 | |
|
202
6960625e62e0
fix getmaxy() not being available in POSIX curses
Mike Becker <universe@uap-core.de>
parents:
199
diff
changeset
|
985 | move(input_getmaxy()-5, 0); |
| 129 | 986 | if (gamestate->wresign) { |
| 987 | addstr("White resigned.\n"); | |
| 988 | } else if (gamestate->bresign) { | |
| 989 | addstr("Black resigned.\n"); | |
| 990 | } else if (gamestate->remis) { | |
| 991 | addstr("The game ended remis.\n"); | |
| 992 | } else if (gamestate->stalemate) { | |
| 993 | addstr("The game ended in a stalemate.\n"); | |
|
174
2929e86c4817
add info text in game review for threefold repetition
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
994 | } else if (gamestate->threefold) { |
|
2929e86c4817
add info text in game review for threefold repetition
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
995 | addstr("The game was drawn after threefold repetition.\n"); |
|
179
5ef724e21702
implement draw due to insufficient material
Mike Becker <universe@uap-core.de>
parents:
176
diff
changeset
|
996 | } else if (gamestate->nomaterial) { |
|
5ef724e21702
implement draw due to insufficient material
Mike Becker <universe@uap-core.de>
parents:
176
diff
changeset
|
997 | addstr("The game is drawn due to insufficient material.\n"); |
| 129 | 998 | } else if (gamestate->checkmate) { |
|
219
24b866230dd4
identify all and fix some occurrences where the new move_start offset matters
Mike Becker <universe@uap-core.de>
parents:
212
diff
changeset
|
999 | addstr(current_color(gamestate) == WHITE ? "White" : "Black"); |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1000 | addstr(" was checkmated.\n"); |
| 129 | 1001 | } else if (gamestate->ragequit) { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1002 | addstr("Your opponent disconnected.\n"); |
| 129 | 1003 | } |
| 1004 | addstr("\nPress 'q' to quit, 's' to save the position as PGN, or\n" | |
| 1005 | "arrow keys, home/end, page up/down to review the game.\n"); | |
| 1006 | flushinp(); | |
| 1007 | redraw = false; | |
| 1008 | } | |
| 1009 | c = getch(); | |
| 1010 | if (c == 's') { | |
| 1011 | addch('\r'); | |
| 1012 | echo(); | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1013 | save_pgn(&viewedstate); |
| 129 | 1014 | noecho(); |
| 1015 | redraw = true; | |
| 1016 | } else if (c == KEY_UP || c == KEY_LEFT) { | |
| 1017 | if (viewedmove > 0) { | |
| 1018 | viewedmove--; | |
| 1019 | redraw = true; | |
| 1020 | } | |
| 1021 | } else if (c == KEY_DOWN || c == KEY_RIGHT) { | |
| 1022 | if (viewedmove < gamestate->movecount) { | |
| 1023 | viewedmove++; | |
| 1024 | redraw = true; | |
| 1025 | } | |
| 1026 | } else if (c == KEY_HOME) { | |
| 1027 | viewedmove = 0; | |
| 1028 | redraw = true; | |
| 1029 | } else if (c == KEY_END) { | |
| 1030 | viewedmove = gamestate->movecount; | |
| 1031 | redraw = true; | |
| 1032 | } else if (c == KEY_PPAGE) { | |
| 1033 | if (viewedmove > page_moves) { | |
| 1034 | viewedmove -= page_moves; | |
| 1035 | } else { | |
| 1036 | viewedmove = 0; | |
| 1037 | } | |
| 1038 | redraw = true; | |
| 1039 | } else if (c == KEY_NPAGE) { | |
| 1040 | viewedmove += page_moves; | |
| 1041 | if (viewedmove > gamestate->movecount) { | |
| 1042 | viewedmove = gamestate->movecount; | |
| 1043 | } | |
| 1044 | redraw = true; | |
| 1045 | } | |
| 1046 | } while (c != 'q'); | |
| 1047 | echo(); | |
| 1048 | gamestate_cleanup(&viewedstate); | |
| 1049 | } | |
| 1050 | ||
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1051 | static void game_play_singlemachine(GameState *gamestate) { |
|
202
6960625e62e0
fix getmaxy() not being available in POSIX curses
Mike Becker <universe@uap-core.de>
parents:
199
diff
changeset
|
1052 | inputy = input_getmaxy() - 6; |
| 129 | 1053 | |
| 194 | 1054 | Color curcol = current_color(gamestate); |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1055 | bool running = is_game_running(gamestate); |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1056 | while (running) { |
| 129 | 1057 | clear(); |
| 194 | 1058 | Color perspective = settings.disableflip ? WHITE : curcol; |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1059 | draw_board(gamestate, perspective); |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1060 | running = !domove_singlemachine(gamestate, curcol); |
| 129 | 1061 | curcol = opponent_color(curcol); |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1062 | } |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1063 | game_review(gamestate); |
| 129 | 1064 | } |
| 1065 | ||
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1066 | static void game_play(GameState *gamestate, int opponent, bool as_client) { |
|
202
6960625e62e0
fix getmaxy() not being available in POSIX curses
Mike Becker <universe@uap-core.de>
parents:
199
diff
changeset
|
1067 | inputy = input_getmaxy() - 6; |
| 129 | 1068 | |
| 194 | 1069 | Color mycolor = gamestate->info.servercolor; |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1070 | if (as_client) { |
| 129 | 1071 | mycolor = opponent_color(mycolor); |
| 1072 | } | |
| 1073 | ||
|
133
c58ae152733e
simplify FEN generation and add current_color() function to rules
Mike Becker <universe@uap-core.de>
parents:
132
diff
changeset
|
1074 | bool myturn = current_color(gamestate) == mycolor; |
| 129 | 1075 | |
| 1076 | bool running; | |
| 1077 | do { | |
| 1078 | clear(); | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1079 | draw_board(gamestate, mycolor); |
| 129 | 1080 | if (myturn) { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1081 | running = !sendmove(gamestate, opponent, mycolor); |
| 129 | 1082 | } else { |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1083 | running = !recvmove(gamestate, opponent, mycolor); |
| 129 | 1084 | } |
| 1085 | myturn ^= true; | |
| 1086 | } while (running); | |
| 1087 | } | |
| 1088 | ||
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1089 | static void dump_gameinfo(GameState *gamestate) { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1090 | GameInfo *gameinfo = &gamestate->info; |
| 129 | 1091 | int serverwhite = gameinfo->servercolor == WHITE; |
| 1092 | attron(A_UNDERLINE); | |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1093 | addstr("Game details\n"); |
| 129 | 1094 | attroff(A_UNDERLINE); |
| 1095 | printw(" Server: %s\n Client: %s\n", | |
| 1096 | serverwhite?"White":"Black", serverwhite?"Black":"White" | |
| 1097 | ); | |
| 1098 | if (gameinfo->timecontrol) { | |
| 1099 | if (gameinfo->time % 60) { | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1100 | printw(" Time limit: %us + %us", |
| 129 | 1101 | gameinfo->time, gameinfo->addtime); |
| 1102 | } else { | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1103 | printw(" Time limit: %um + %us", |
| 129 | 1104 | gameinfo->time/60, gameinfo->addtime); |
| 1105 | } | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1106 | if (gameinfo->delay) { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1107 | printw(" (with %us delay)", gameinfo->delay); |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1108 | } |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1109 | addch('\n'); |
| 129 | 1110 | } else { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1111 | addstr(" No time limit\n"); |
| 129 | 1112 | } |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1113 | addch('\n'); |
| 129 | 1114 | for (unsigned i = 0 ; i < gamestate->movecount ; i++) { |
| 1115 | if (i % 2 == 0) { | |
|
219
24b866230dd4
identify all and fix some occurrences where the new move_start offset matters
Mike Becker <universe@uap-core.de>
parents:
212
diff
changeset
|
1116 | // TODO: add move_start offset |
| 129 | 1117 | printw("%d. %s", 1+i/2, gamestate->moves[i].string); |
| 1118 | } else { | |
| 1119 | printw("%s", gamestate->moves[i].string); | |
| 1120 | } | |
| 194 | 1121 | // only five moves reliably fit into one screen rank |
| 129 | 1122 | if ((i+1) % 10) { |
| 1123 | addch(' '); | |
| 1124 | } else { | |
| 1125 | addch('\n'); | |
| 1126 | } | |
| 1127 | } | |
| 1128 | refresh(); | |
| 1129 | } | |
| 1130 | ||
| 1131 | static int server_fd = -1; | |
| 1132 | static void interrupt_listen(int sig) { | |
|
193
d1420f5c5704
increase type safety + add backwards compatibility including C99
Mike Becker <universe@uap-core.de>
parents:
192
diff
changeset
|
1133 | (void)sig; /* unused */ |
| 129 | 1134 | if (server_fd > -1) { |
| 1135 | // this interrupts | |
| 1136 | close(server_fd); | |
| 1137 | } | |
| 1138 | } | |
| 1139 | ||
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1140 | static int server_open(Server *server) { |
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1141 | addstr("\nListening for client...\n"); |
| 129 | 1142 | refresh(); |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1143 | if (settings.usedomainsocket |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1144 | ? net_create_sock(server, settings.serverhost) |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1145 | : net_create_tcp(server, settings.port)) { |
| 129 | 1146 | addstr("Server creation failed"); |
| 1147 | return 1; | |
| 1148 | } | |
| 1149 | ||
| 1150 | // allow Ctrl+C to interrupt the listening process | |
| 1151 | server_fd = server->fd; | |
| 1152 | signal(SIGINT, interrupt_listen); | |
| 1153 | ||
| 1154 | if (net_listen(server)) { | |
| 1155 | addstr("Listening for client failed or interrupted"); | |
| 1156 | return 1; | |
| 1157 | } | |
| 1158 | ||
| 1159 | // restore default action | |
| 1160 | signal(SIGINT, SIG_DFL); | |
| 1161 | ||
| 1162 | return 0; | |
| 1163 | } | |
| 1164 | ||
| 1165 | static int server_handshake(Client *client) { | |
| 1166 | net_send_code(client->fd, NETCODE_VERSION); | |
| 1167 | if (net_recieve_code(client->fd) != NETCODE_VERSION) { | |
| 1168 | addstr("Client uses an incompatible software version."); | |
| 1169 | return 1; | |
| 1170 | } | |
| 1171 | ||
| 1172 | addstr("Client connected - transmitting gameinfo..."); | |
| 1173 | refresh(); | |
| 1174 | ||
| 1175 | return 0; | |
| 1176 | } | |
| 1177 | ||
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1178 | static int server_run(GameState *gamestate) { |
| 129 | 1179 | Server server; |
| 1180 | ||
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1181 | dump_gameinfo(gamestate); |
| 129 | 1182 | |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1183 | if (server_open(&server)) { |
| 129 | 1184 | net_destroy(&server); |
| 1185 | return 1; | |
| 1186 | } | |
| 1187 | ||
| 1188 | if (server_handshake(server.client)) { | |
| 1189 | net_destroy(&server); | |
| 1190 | return 1; | |
| 1191 | } | |
| 1192 | ||
| 1193 | int fd = server.client->fd; | |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1194 | NetGameInfo gi = hton_gi(gamestate->info); |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1195 | if (settings.continuepgn) { |
| 129 | 1196 | /* Continue game, send PGN data */ |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1197 | uint16_t mc = gamestate->movecount; |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1198 | size_t pgndata_size = NETGI_LEN + 2 + mc * NETMOVE_LEN; |
| 129 | 1199 | char *pgndata = malloc(pgndata_size); |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1200 | memcpy(pgndata, &gi, NETGI_LEN); |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1201 | unsigned offset = NETGI_LEN; |
|
183
39aa77b7188b
fix missing byte-order conversion in ntoh_move() and change protocol byte order to little-endian
Mike Becker <universe@uap-core.de>
parents:
182
diff
changeset
|
1202 | uint16_t mcn = net_htons(mc); |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1203 | memcpy(pgndata+offset, &mcn, 2); |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1204 | offset += 2; |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1205 | for (unsigned i = 0 ; i < mc ; i++) { |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1206 | NetMove nmove = hton_move(gamestate->moves[i]); |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1207 | memcpy(pgndata+offset, &nmove, NETMOVE_LEN); |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1208 | offset += NETMOVE_LEN; |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1209 | } |
| 129 | 1210 | net_send_data(fd, NETCODE_PGNDATA, pgndata, pgndata_size); |
| 1211 | free(pgndata); | |
| 1212 | } else { | |
| 1213 | /* Start new game */ | |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1214 | net_send_data(fd, NETCODE_GAMEINFO, &gi, NETGI_LEN); |
| 129 | 1215 | } |
| 1216 | addstr("\rClient connected - awaiting challenge acceptance..."); | |
| 1217 | refresh(); | |
| 1218 | int code = net_recieve_code(fd); | |
| 1219 | if (code == NETCODE_ACCEPT) { | |
| 1220 | addstr("\rClient connected - challenge accepted."); | |
| 1221 | clrtoeol(); | |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1222 | game_play(gamestate, fd, false); |
| 129 | 1223 | net_destroy(&server); |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1224 | game_review(gamestate); |
| 129 | 1225 | } else if (code == NETCODE_DECLINE) { |
| 1226 | addstr("\rClient connected - challenge declined."); | |
| 1227 | clrtoeol(); | |
| 1228 | net_destroy(&server); | |
| 1229 | } else if (code == NETCODE_CONNLOST) { | |
| 1230 | addstr("\rClient connected - but gave no response."); | |
| 1231 | clrtoeol(); | |
| 1232 | net_destroy(&server); | |
| 1233 | } else { | |
| 1234 | addstr("\rInvalid client response"); | |
| 1235 | clrtoeol(); | |
| 1236 | net_destroy(&server); | |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1237 | return 1; |
| 129 | 1238 | } |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1239 | return 0; |
| 129 | 1240 | } |
| 1241 | ||
| 1242 | ||
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1243 | static int client_connect(Server *server) { |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1244 | if (settings.usedomainsocket |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1245 | ? net_find_sock(server, settings.serverhost) |
|
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1246 | : net_find_tcp(server, settings.serverhost, settings.port)) { |
| 129 | 1247 | addstr("Can't find server"); |
| 1248 | return 1; | |
| 1249 | } | |
| 1250 | ||
| 1251 | if (net_connect(server)) { | |
| 1252 | addstr("Can't connect to server"); | |
| 1253 | return 1; | |
| 1254 | } | |
| 1255 | ||
| 1256 | return 0; | |
| 1257 | } | |
| 1258 | ||
| 1259 | static int client_handshake(Server *server) { | |
|
180
0fed680c487c
fix that client is not sending netcode version back on version mismatch
Mike Becker <universe@uap-core.de>
parents:
179
diff
changeset
|
1260 | uint8_t server_version = net_recieve_code(server->fd); |
|
0fed680c487c
fix that client is not sending netcode version back on version mismatch
Mike Becker <universe@uap-core.de>
parents:
179
diff
changeset
|
1261 | net_send_code(server->fd, NETCODE_VERSION); |
|
0fed680c487c
fix that client is not sending netcode version back on version mismatch
Mike Becker <universe@uap-core.de>
parents:
179
diff
changeset
|
1262 | if (server_version != NETCODE_VERSION) { |
| 129 | 1263 | addstr("Server uses an incompatible software version."); |
| 1264 | return 1; | |
| 1265 | } | |
| 1266 | ||
|
210
7ad6c62f6bdc
replace unnecessary printw() calls with addstr() or addch()
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1267 | addstr("Connection established!\n\n"); |
| 129 | 1268 | refresh(); |
| 1269 | ||
| 1270 | return 0; | |
| 1271 | } | |
| 1272 | ||
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1273 | static int client_run(GameState *gamestate) { |
| 129 | 1274 | Server server; |
| 1275 | ||
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1276 | if (client_connect(&server)) { |
| 129 | 1277 | net_destroy(&server); |
| 1278 | return 1; | |
| 1279 | } | |
| 1280 | ||
| 1281 | if (client_handshake(&server)) { | |
| 1282 | net_destroy(&server); | |
| 1283 | return 1; | |
| 1284 | } | |
| 1285 | ||
| 1286 | uint8_t code = net_recieve_code(server.fd); | |
| 1287 | bool played = false; | |
| 1288 | if (code == NETCODE_GAMEINFO) { | |
| 1289 | /* Start new game */ | |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1290 | NetGameInfo gi; |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1291 | net_recieve_data(server.fd, &gi, NETGI_LEN); |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1292 | gamestate->info = ntoh_gi(gi); |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1293 | dump_gameinfo(gamestate); |
| 129 | 1294 | if (prompt_yesno("Accept challenge")) { |
| 1295 | net_send_code(server.fd, NETCODE_ACCEPT); | |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1296 | game_play(gamestate, server.fd, true); |
| 129 | 1297 | played = true; |
| 1298 | } else { | |
| 1299 | net_send_code(server.fd, NETCODE_DECLINE); | |
| 1300 | } | |
| 1301 | } else if (code == NETCODE_PGNDATA) { | |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1302 | NetGameInfo gi; |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1303 | net_recieve_data(server.fd, &gi, NETGI_LEN); |
|
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1304 | gamestate->info = ntoh_gi(gi); |
| 129 | 1305 | uint16_t mc; |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1306 | net_recieve_data(server.fd, &mc, 2); |
|
183
39aa77b7188b
fix missing byte-order conversion in ntoh_move() and change protocol byte order to little-endian
Mike Becker <universe@uap-core.de>
parents:
182
diff
changeset
|
1307 | mc = net_ntohs(mc); |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1308 | char *movedata = malloc(mc * NETMOVE_LEN); |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1309 | net_recieve_data(server.fd, movedata, mc*NETMOVE_LEN); |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1310 | unsigned offset = 0; |
| 129 | 1311 | for (size_t i = 0 ; i < mc ; i++) { |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1312 | NetMove nmove; |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1313 | memcpy(&nmove, movedata+offset, NETMOVE_LEN); |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1314 | offset += NETMOVE_LEN; |
|
184
93c81539b702
fix byte-order problem in GameInfo and change decline reason to one byte
Mike Becker <universe@uap-core.de>
parents:
183
diff
changeset
|
1315 | Move move = ntoh_move(nmove); |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1316 | format_move(gamestate, &move); |
|
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1317 | apply_move(gamestate, &move); |
| 129 | 1318 | } |
|
182
04c65336777f
start fixing the network protocol
Mike Becker <universe@uap-core.de>
parents:
180
diff
changeset
|
1319 | free(movedata); |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1320 | dump_gameinfo(gamestate); |
| 129 | 1321 | if (prompt_yesno( |
| 1322 | "\n\nServer wants to continue a game. Accept challenge")) { | |
| 1323 | net_send_code(server.fd, NETCODE_ACCEPT); | |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1324 | game_play(gamestate, server.fd, true); |
| 129 | 1325 | played = true; |
| 1326 | } else { | |
| 1327 | net_send_code(server.fd, NETCODE_DECLINE); | |
| 1328 | } | |
| 1329 | } else { | |
| 1330 | addstr("Server sent invalid gameinfo."); | |
| 1331 | net_destroy(&server); | |
| 1332 | return 1; | |
| 1333 | } | |
| 1334 | ||
| 1335 | if (played) { | |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1336 | game_review(gamestate); |
| 129 | 1337 | } |
| 1338 | ||
| 1339 | net_destroy(&server); | |
| 1340 | return 0; | |
| 1341 | } | |
| 1342 | ||
| 0 | 1343 | int main(int argc, char **argv) { |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
1344 | srand(time(NULL)); |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
1345 | |
|
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
1346 | init_settings(); |
|
130
3fc6b1d6cbe9
implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents:
129
diff
changeset
|
1347 | if (get_settings(argc, argv)) { |
|
2
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
1348 | return 1; |
|
0a08f79c320d
fixed network code + added game info and transmission of game info
Mike Becker <universe@uap-core.de>
parents:
1
diff
changeset
|
1349 | } |
| 52 | 1350 | |
|
23
824c9522ce66
introduced game state structure
Mike Becker <universe@uap-core.de>
parents:
16
diff
changeset
|
1351 | initscr(); |
|
34
c4d4b8a8f902
added nonblocking read for network games + minor build system fixes
Mike Becker <universe@uap-core.de>
parents:
33
diff
changeset
|
1352 | halfdelay(1); |
|
80
b980a7192b5a
replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents:
78
diff
changeset
|
1353 | keypad(stdscr, true); |
|
7
41468077b5bb
implemented chess board and remis/surrender messages
Mike Becker <universe@uap-core.de>
parents:
5
diff
changeset
|
1354 | if (has_colors()) { |
|
41468077b5bb
implemented chess board and remis/surrender messages
Mike Becker <universe@uap-core.de>
parents:
5
diff
changeset
|
1355 | start_color(); |
|
41468077b5bb
implemented chess board and remis/surrender messages
Mike Becker <universe@uap-core.de>
parents:
5
diff
changeset
|
1356 | init_colorpairs(); |
| 35 | 1357 | bkgd(COLOR_PAIR(COL_APP)); |
|
7
41468077b5bb
implemented chess board and remis/surrender messages
Mike Becker <universe@uap-core.de>
parents:
5
diff
changeset
|
1358 | } else { |
|
41468077b5bb
implemented chess board and remis/surrender messages
Mike Becker <universe@uap-core.de>
parents:
5
diff
changeset
|
1359 | endwin(); |
|
206
f8b9cdf60cf4
fix that error message about non-colored terminals was printed before ending the curses session
Mike Becker <universe@uap-core.de>
parents:
202
diff
changeset
|
1360 | fprintf(stderr, "Non-colored terminals are not supported yet.\n"); |
|
7
41468077b5bb
implemented chess board and remis/surrender messages
Mike Becker <universe@uap-core.de>
parents:
5
diff
changeset
|
1361 | return EXIT_FAILURE; |
|
41468077b5bb
implemented chess board and remis/surrender messages
Mike Becker <universe@uap-core.de>
parents:
5
diff
changeset
|
1362 | } |
|
94
864f59271974
implement option to play via Unix domain socket
Mike Becker <universe@uap-core.de>
parents:
92
diff
changeset
|
1363 | atexit(cleanup); |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1364 | |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1365 | GameState gamestate; |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1366 | gamestate_init(&gamestate); |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1367 | settings_apply(&gamestate); |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1368 | |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1369 | int exitcode = EXIT_SUCCESS; |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1370 | |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1371 | if (settings.continuepgn) { |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1372 | FILE *pgnfile = fopen(settings.continuepgn, "r"); |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1373 | if (pgnfile) { |
|
209
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1374 | pgn_result result = read_pgn(pgnfile, &gamestate); |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1375 | fclose(pgnfile); |
|
209
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1376 | if (result.code) { |
|
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1377 | printw("Invalid PGN content at position %zu", result.position); |
|
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1378 | if (result.move_half_number) { |
|
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1379 | unsigned hm = result.move_half_number - 1; |
|
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1380 | printw(" (move %u, %s)", 1+hm/2, hm%2 ? "black":"white"); |
|
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1381 | } |
|
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1382 | printw(":\n%s", pgn_error_str(result.code)); |
|
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1383 | if (result.code == pgn_error_move) { |
|
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1384 | addch(' '); |
|
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1385 | eval_move_failed_msg(result.move_error); |
|
dc4f34426c66
improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents:
208
diff
changeset
|
1386 | } |
|
212
16a114c84ff5
fix missing test adaptation for pgn_result
Mike Becker <universe@uap-core.de>
parents:
211
diff
changeset
|
1387 | addch('\n'); |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1388 | exitcode = EXIT_FAILURE; |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1389 | } |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1390 | /* clear resignation and remis flags to allow game continuation */ |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1391 | gamestate.wresign = gamestate.bresign = gamestate.remis = false; |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1392 | } else { |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1393 | printw("Can't read PGN file (%s)\n", strerror(errno)); |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1394 | exitcode = EXIT_FAILURE; |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1395 | } |
|
26
e0a76ee1bb2b
introduced single machine mode
Mike Becker <universe@uap-core.de>
parents:
23
diff
changeset
|
1396 | } |
|
175
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1397 | |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1398 | if (exitcode == EXIT_SUCCESS) { |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1399 | if (settings.singlemachine || !is_game_running(&gamestate)) { |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1400 | game_play_singlemachine(&gamestate); |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1401 | } else if (settings.ishost) { |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1402 | exitcode = server_run(&gamestate); |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1403 | } else { |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1404 | exitcode = client_run(&gamestate); |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1405 | } |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1406 | } |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1407 | |
|
e0e061cf4829
allow continuing resigned or (actively) drawn games
Mike Becker <universe@uap-core.de>
parents:
174
diff
changeset
|
1408 | gamestate_cleanup(&gamestate); |
|
46
4dcfb4c58b6d
netcode is now aware of connection losses
Mike Becker <universe@uap-core.de>
parents:
35
diff
changeset
|
1409 | |
|
202
6960625e62e0
fix getmaxy() not being available in POSIX curses
Mike Becker <universe@uap-core.de>
parents:
199
diff
changeset
|
1410 | mvaddstr(input_getmaxy()-1, 0, |
|
46
4dcfb4c58b6d
netcode is now aware of connection losses
Mike Becker <universe@uap-core.de>
parents:
35
diff
changeset
|
1411 | "Game has ended. Press any key to leave..."); |
|
50
41017d0a72c5
added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
47
diff
changeset
|
1412 | clrtoeol(); |
|
46
4dcfb4c58b6d
netcode is now aware of connection losses
Mike Becker <universe@uap-core.de>
parents:
35
diff
changeset
|
1413 | refresh(); |
|
4dcfb4c58b6d
netcode is now aware of connection losses
Mike Becker <universe@uap-core.de>
parents:
35
diff
changeset
|
1414 | cbreak(); |
|
4dcfb4c58b6d
netcode is now aware of connection losses
Mike Becker <universe@uap-core.de>
parents:
35
diff
changeset
|
1415 | flushinp(); |
|
4dcfb4c58b6d
netcode is now aware of connection losses
Mike Becker <universe@uap-core.de>
parents:
35
diff
changeset
|
1416 | getch(); |
|
4dcfb4c58b6d
netcode is now aware of connection losses
Mike Becker <universe@uap-core.de>
parents:
35
diff
changeset
|
1417 | |
|
4dcfb4c58b6d
netcode is now aware of connection losses
Mike Becker <universe@uap-core.de>
parents:
35
diff
changeset
|
1418 | return exitcode; |
| 0 | 1419 | } |
| 1420 |