Skip to content

Instantly share code, notes, and snippets.

@ww24
Created January 16, 2014 08:21
Show Gist options
  • Save ww24/8451487 to your computer and use it in GitHub Desktop.
Save ww24/8451487 to your computer and use it in GitHub Desktop.
Number Guessing Game
#include <windows.h>
#include <assert.h>
#define EXITIF(COND) if (COND) { assert(!(COND)); exit(EXIT_FAILURE); }
void server(short port)
{
WSADATA wsaData;
int sock, newsock, sinlen, r, result, num;
u_long ulnum;
struct sockaddr_in sinme, sinhim;
// ソケット利用の宣言
WSAStartup(MAKEWORD(1, 1), &wsaData);
// アドレス情報の設定
sinme.sin_family = AF_INET;
sinme.sin_port = htons(port);
sinme.sin_addr.s_addr = htonl(INADDR_ANY);
// ソケットの生成
sock = socket(AF_INET, SOCK_STREAM, 0);
EXITIF(sock < 0);
// ソケットに IP アドレスとポート番号を結合
r = bind(sock, (struct sockaddr *)&sinme, sizeof(sinme));
EXITIF(r < 0);
// ソケットへの接続を待つ (受信キューの設定)
r = listen(sock, 5);
EXITIF(r < 0);
// クライアントの接続待機
puts("Waiting...");
// 接続要求の受付
sinlen = sizeof(sinhim);
newsock = accept(sock, (struct sockaddr *)&sinhim, &sinlen);
EXITIF(newsock < 0);
puts("Please enter a natural number less than 100. (include 100)");
printf("number > ");
scanf("%d", &num);
puts("Game Start!");
// ゲーム開始イベントの送信
ulnum = ntohl(200);
r = send(newsock, (char *)&ulnum, sizeof(ulnum), 0);
EXITIF(r < 0);
for (;;) {
// クライアントの入力待機
puts("Waiting...");
// データの受信
r = recv(newsock, (char *)&ulnum, sizeof(ulnum), 0);
EXITIF(r < 0);
result = htonl(ulnum);
// number 確認
if (num > result) {
printf("%lu is wrong.\n", result);
result = 300;
} else if (num < result) {
printf("%lu is wrong.\n", result);
result = 100;
} else {
printf("%lu is correct!\n", result);
result = 200;
}
// 結果送信
ulnum = ntohl(result);
r = send(newsock, (char *)&ulnum, sizeof(ulnum), 0);
EXITIF(r < 0);
if (result == 200)
break;
}
// ソケット利用の後処理
closesocket(newsock);
closesocket(sock);
WSACleanup();
}
void client(char *ip_addr, short port)
{
WSADATA wsaData;
int sock, i, r, result, num;
u_long ulnum;
struct sockaddr_in sinhim;
char message[1024];
// ソケット利用の宣言
WSAStartup(MAKEWORD(1, 1), &wsaData);
// アドレス情報の設定
sinhim.sin_family = AF_INET;
sinhim.sin_port = htons(port);
sinhim.sin_addr.s_addr = inet_addr(ip_addr);
// ソケットの生成
sock = socket(AF_INET, SOCK_STREAM, 0);
EXITIF(sock < 0);
// 送信先のアドレスポート指定
r = connect(sock, (struct sockaddr *)&sinhim, sizeof(struct sockaddr_in));
EXITIF(r < 0);
puts("Waiting...");
// ゲーム開始イベントの受信
r = recv(sock, (char *)&ulnum, sizeof(ulnum), 0);
EXITIF(r < 0);
result = ntohl(ulnum);
EXITIF(result != 200);
puts("Game Start!");
puts("Guess a number which entered by server side.");
puts("(Hint: Natural number less than 100. [include 100])");
for (;;) {
// ユーザの入力待ち
printf("number > ");
scanf("%d", &num);
// データの送信
ulnum = htonl(num);
r = send(sock, (char *)&ulnum, sizeof(ulnum), 0);
EXITIF(r < 0);
// 結果の受信
r = recv(sock, (char *)&ulnum, sizeof(ulnum), 0);
EXITIF(r < 0);
result = ntohl(ulnum);
// 結果表示
if (result > 200) {
puts("Fail.");
printf("Hint: Its number is greater than %d.\n", num);
} else if (result < 200) {
puts("Fail.");
printf("Hint: Its number is less than %d.\n", num);
} else {
puts("Success!");
break;
}
}
// ソケット利用の後処理
closesocket(sock);
WSACleanup();
}
int main(void)
{
// IP アドレス, port 番号指定
char *ip_addr = "127.0.0.1";
short port = 10001;
puts("Number Guessing Game");
puts("--------------------");
// 起動時メニュー
for (;;) {
puts("Please enter s or c.");
puts("Start Server: s");
puts("Start Client: c");
puts("Quit : q");
switch (getchar()) {
case 's':
server(port);
break;
case 'c':
client(ip_addr, port);
break;
case 'q':
puts("Bye.");
break;
default:
puts("");
continue;
}
break;
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment