Created
August 5, 2018 04:47
-
-
Save xreiju/6b3c19a722c7ad59de050083736f413e to your computer and use it in GitHub Desktop.
dependency: vibe-d
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import vibe.http.websockets; | |
import vibe.core.log; | |
import vibe.core.core; | |
import vibe.inet.url; | |
import std.json; | |
import std.net.curl; | |
import std.parallelism; | |
import std.random; | |
import std.concurrency; | |
import std.stdio; | |
import std.algorithm; | |
import std.conv; | |
import std.string; | |
import std.range; | |
const baseURL = "misskey.xyz"; | |
const apiURL = "https://" ~ baseURL ~ "/api"; | |
const wsURL = "wss://" ~ baseURL; | |
string userid, i; | |
string jsonPost(string url, string[string] param) { | |
HTTP http = HTTP(); | |
http.addRequestHeader("Content-Type", "application/json"); | |
return post(url, JSONValue(param).toString, http).to!string; | |
} | |
auto connectReversi() { | |
logInfo(wsURL ~ "/?i=" ~ i); | |
auto url = URL(wsURL ~ "/games/reversi?i=" ~ i); | |
auto ws = connectWebSocket(url); | |
logInfo("WebSocket connected"); | |
return ws; | |
} | |
void main(string[] args) { | |
if(args.length <= 2) return; | |
userid = args[1]; | |
i = args[2]; | |
auto ws = connectReversi(); | |
while(ws.waitForData()) { | |
auto txt = ws.receiveText; | |
auto json = parseJSON(txt); | |
auto data = json["body"]; | |
auto type = json["type"].str; | |
if(type == "invited") { | |
logInfo("Got invited by %s!", data["parent"]["username"].str); | |
auto res = jsonPost(apiURL~"/games/reversi/match", | |
["i": i, "userId": data["parent"]["id"].str] | |
).parseJSON; | |
spawn(&startGame, i, res["id"].str); // 各試合用のプロセスをつくる | |
} | |
} | |
logFatal("Connection lost!"); | |
} | |
void startGame(string i, string id) { | |
logInfo("received: %s", id); | |
auto url = URL("%s/games/reversi-game?i=%s&game=%s".format(wsURL, i, id)); | |
auto ws = connectWebSocket(url); | |
logInfo("Game %s's websocket connected", id); | |
logInfo(url.to!string); | |
ws.send(["type": "accept"].JSONValue.toString); | |
Othello o; | |
while(ws.waitForData()) { | |
// なぜかtype: setが一回来たあと多分ここですら実行されなくなってしまう | |
auto txt = ws.receiveText; | |
auto json = txt.parseJSON; | |
auto type = json["type"].str; | |
auto data = json["body"]; | |
json.writeln; | |
type.writeln; | |
switch(type) { | |
case "started": | |
data["user1Id"].str.writeln; | |
data["black"].integer.writeln; | |
bool tmp = data["user1Id"].str == userid && data["black"].integer == 1 || data["user2Id"].str == userid && data["black"].integer == 2; | |
o = new Othello(data["settings"]["map"].to!string[].to!(char[][]), tmp); | |
//if(tmp) ws.send(["type": "set", "pos": o.think().to!string].JSONValue.toString); | |
break; | |
case "set": | |
o.onSet(data); | |
break; | |
default: | |
break; | |
} | |
} | |
// ここにもこない | |
logFatal("connection lost! %s", id); | |
} | |
class Othello { | |
char[][] board; | |
const ulong height, width; | |
bool botColor; | |
this(char[][] board, bool botColor) { | |
this.board = board; | |
this.botColor = botColor; | |
height = board.length; | |
width = board[0].length; | |
foreach(i; 0..height) foreach(j; 0..width) { | |
if(isPlaceable(i, j)) board[i][j] = 'o'; | |
} | |
board.each!writeln; | |
} | |
auto dh = [1,1,0,-1,-1,-1,0,1]; | |
auto dw = [0,-1,-1,-1,0,1,1,1]; | |
bool isPlaceable(ulong h, ulong w) { | |
if(h >= height || w >= width) | |
return false; | |
if(board[h][w] != '-') | |
return false; | |
foreach(i; 8.iota) { | |
if(isPlaceable(h, w, dh[i], dw[i])) | |
return true; | |
} | |
return false; | |
} | |
// TODO: バグだらけ^q^ 適当にネットから拾ってきた | |
bool isPlaceable(ulong h, ulong w, int dh, int dw) { | |
char myStone = botColor ? 'b' : 'w'; | |
h += dh, w += dw; | |
if(h < 0 || h >= height || w < 0 || w >= width) | |
return false; | |
if(board[h][w] == myStone) return false; | |
if(board[h][w] == ' ') return false; | |
while(h >= 0 && h < height && w >= 0 && w < width) { | |
if(board[h][w] == ' ') | |
return false; | |
if(board[h][w] == myStone) | |
return true; | |
h += dh; | |
w += dw; | |
} | |
return false; | |
} | |
void onSet(JSONValue data) { | |
auto pos = data["pos"].integer; | |
pos.writeln; | |
board[pos/width][pos%width] = data["color"].str[0]; | |
foreach(i; 0..height) foreach(j; 0..width) { | |
if(isPlaceable(i, j)) board[i][j] = 'o'; | |
} | |
board.each!writeln; | |
} | |
// TODO | |
int think() { | |
return 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment