'update'
[rpsls-web.git] / rpsls.js
CommitLineData
bbb90bba
BA
1const socket = io();
2
3const getV = (field) => localStorage.getItem(field);
4
5const Login = {
6 view: function() {
7 return m("input[type=text][placeholder=User name]", {
8 autofocus: true,
9 onchange(e) {Login.username = e.currentTarget.value},
10 onkeyup: Login.process
11 });
12 },
13 process: function(e) {
14 if (e.keyCode == 13) socket.emit("login", e.target.value);
15 }
16};
17
18let Seek = {
19 searching: false,
20 seekGame: function() {
21 // If not logged in, redirect
22 if (!getV("name")) m.route.set("/login");
23 else {
24 socket.emit("seek", {uid: getV("uid"), name: getV("name")});
25 Seek.searching = true;
26 }
27 },
2c1541ba 28 view: function(vnode) {
bbb90bba
BA
29 if (Seek.searching)
30 return m("img.animated", {src: "assets/searching.gif"});
2c1541ba
BA
31 return m("button", {onclick: Seek.seekGame}, "Play");
32 }
bbb90bba
BA
33};
34
35const Choices =
36 {'r':"Rock",'p':"Paper",'s':"Scissors",'l':"Lizard",'k':"Spock",'?':"what"};
37const Win =
38 {'r':['s','l'], 'p':['r','k'], 's':['p','l'], 'l':['p','k'], 'k':['r','s']};
39const MAX_POINTS = 7;
40
41let Play = {
42 gid: 0,
43 mymove: "",
44 oppmove: "",
45 myselect: "?",
46 oppselect: "?",
47 mypoints: 0,
48 oppoints: 0,
49 mnum: 0,
50 oppid: 0,
51 oppname: "",
52 gameover: false,
53 initGame: function(msg) {
54 Play.gid = msg.gid;
55 Play.oppid = msg.oppid;
56 Play.oppname = msg.oppname;
57 Play.gameover = false;
58 for (const v of ["mymove","oppmove"]) Play[v] = "";
59 for (const v of ["myselect","oppselect"]) Play[v] = "?";
60 for (const v of ["mnum","mypoints","oppoints"]) Play[v] = 0;
61 },
62 compareMoves: function() {
63 Play.oppselect = Play.oppmove; //reveal opponent's move only now
64 if (Win[Play.mymove].includes(Play.oppmove)) {
65 if (++Play.mypoints == MAX_POINTS) Play.endGame(true);
f126a42e 66 socket.emit("inc_pts", {uid: getV("uid"), gid:Play.gid});
bbb90bba
BA
67 }
68 else if (Win[Play.oppmove].includes(Play.mymove)) {
69 if (++Play.oppoints == MAX_POINTS) Play.endGame(false);
70 }
71 Play.mnum++;
72 Play.mymove = "";
73 Play.oppmove = "";
74 },
75 endGame: function(Iwin) {
76 Play.gameover = true;
77 setTimeout(() => {
78 if (Iwin) alert("Bravo t'as gagné !");
79 else alert("Pas de chance, t'as perdu...");
80 m.route.set("/seek");
81 }, 1000);
82 },
83 playMove: function(code) {
84 if (Play.mymove || Play.gameover)
85 // I already played, or game is over
86 return;
87 Play.mymove = code;
88 Play.myselect = code;
89 socket.emit("move", {
90 uid: getV("uid"),
91 gid: Play.gid,
92 choice: Play.mymove,
93 mnum: Play.mnum,
94 oppid: Play.oppid
95 });
96 if (Play.oppmove) Play.compareMoves();
97 else Play.oppselect = "?";
98 },
99 view: function() {
100 return m("div", {},
101 [m("h2", {},
102 `${getV("name")} [${Play.mypoints}] vs. ${Play.oppname} [${Play.oppoints}]`)]
103 .concat(
104 [m(".choices", {}, [
105 m("img", {src: "assets/" + Choices[Play.myselect] + ".png"}),
106 m("img", {src: "assets/" + Choices[Play.oppselect] + ".png"})
107 ])]).concat(
108 [m(".options",
109 {style: `opacity:${Play.mymove==''?'1':'0.5'}`},
110 ["r","p","s","l","k"].map((code) => {
111 return m("img", {
112 src: "assets/" + Choices[code] + ".png",
113 onclick: () => Play.playMove(code)
114 })
115 }))])
116 );
117 }
118};
119
120socket.on("login", (msg) => {
121 if (!msg.err) {
122 localStorage.setItem("name", msg.name);
123 localStorage.setItem("uid", msg.uid);
124 m.route.set("/seek");
125 }
126 else alert(msg.err);
127});
128socket.on("play", (msg) => {
129 Seek.searching = false;
130 if (msg.oppid == getV("uid")) {
131 alert("Cannot play against self!");
132 m.redraw(); //TODO: because no DOM interaction... ?
133 }
134 else {
135 Play.initGame(msg);
136 m.route.set("/play");
137 }
138});
139socket.on("move", (msg) => {
140 Play.oppmove = msg.choice;
141 Play.oppselect = "?"; //not showing opponent selection yet!
142 if (Play.mymove) Play.compareMoves();
143 else Play.myselect = "?";
144 m.redraw(); //TODO... (because no DOM interactions)
145});
146
147m.route(document.body, "/seek", {
2c1541ba
BA
148 "/seek": Seek,
149 "/play": Play,
bbb90bba
BA
150 "/login": Login
151});