app.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. // When document is ready initialize app
  2. $(document).ready(function() {
  3. var filter = web3.eth.filter('latest');
  4. filter.watch(function(err, res){
  5. if(!err){
  6. updateUI();
  7. }
  8. else{
  9. console.error("!!!!!!Error Happened!");
  10. filter.stopWatching();
  11. }
  12. });
  13. /// INIT Whisper
  14. web3.Lib.initWhisper()
  15. .then(function(w){
  16. web3.Whisper = w;
  17. });
  18. createUI();
  19. updateUI();
  20. });
  21. ///////////////////
  22. /// UI ////////////
  23. ///////////////////
  24. var matchhash;
  25. var maphash;
  26. var opAccount;
  27. var selectBox;
  28. function createUI(){
  29. selectBox = document.getElementById("accselector");
  30. for (var i = 0; i<web3.eth.accounts.length; i++){
  31. var opt = document.createElement('option');
  32. opt.value = i;
  33. opt.innerHTML = web3.eth.accounts[i];
  34. selectBox.appendChild(opt);
  35. }
  36. selectBox.onchange = function(){
  37. web3.eth.defaultAccount = web3.eth.accounts[selectBox.value];
  38. updateUI(selectBox.value);
  39. }
  40. $("#showMapBtn").click(function(){
  41. updateMapTable(web3.Game.getMapArray());
  42. });
  43. $("#createMatchBtn").click(function(){
  44. var stake = $("#stakeTxt").val();
  45. createMatch(stake);
  46. });
  47. $("#joinMatchBtn").click(function(){
  48. var stake = parseInt($("#stakeTxt").val());
  49. var matchhash = $("#matchhashTxt").val();
  50. joinMatch(stake, matchhash);
  51. });
  52. $("#startGameBtn").click(function(){
  53. startGame();
  54. });
  55. $("#sendSelectMoveBtn").click(function(){
  56. sendSelectMove();
  57. });
  58. $("#sendBetMoveBtn").click(function(){
  59. sendBetMove();
  60. });
  61. $("#sendCallMoveBtn").click(function(){
  62. sendCallMove();
  63. });
  64. $("#sendFoldMoveBtn").click(function(){
  65. sendFoldMove();
  66. });
  67. $("#sendProofMoveBtn").click(function(){
  68. sendProofMove();
  69. });
  70. }
  71. function updateUI(accindex){
  72. updateForAccount();
  73. }
  74. function updateGameUI(state){
  75. $("#mycoins").html(state.coins[web3.eth.defaultAccount]);
  76. $("#opcoins").html(state.coins[web3.eth.opponentAccount]);
  77. $("#pot").html(state.pot);
  78. $("#round").html(state.round);
  79. $("#mybets").html(state.bets[web3.eth.defaultAccount]);
  80. $("#opbets").html(state.bets[web3.eth.opponentAccount]);
  81. var sums = web3.Game.findSums();
  82. $("#mysum").html(sums[web3.eth.defaultAccount]);
  83. $("#opsum").html(sums[web3.eth.opponentAccount]);
  84. updateMapTable(web3.Game.getMapArray(), state);
  85. // console.log("Selected for me: ");
  86. // console.log(state.selected[web3.eth.defaultAccount]);
  87. // console.log("Selected for opponent: ");
  88. // console.log(state.selected[web3.eth.opponentAccount]);
  89. }
  90. function updateForAccount(){
  91. var ethaddr = web3.eth.defaultAccount;
  92. $("#ethaddr").html(ethaddr);
  93. var ethbal = web3.eth.getBalance(ethaddr);
  94. $("#ethbal").html(web3.fromWei(ethbal, "ether").toNumber());
  95. var blockNumber = web3.eth.blockNumber;
  96. $("#block").html("#"+blockNumber);
  97. dbname = web3.db.DBNAME = "CUSTOMDBFOR"+web3.eth.defaultAccount;
  98. Padomima.amInMatch().then(function(res){
  99. $("#inmatch").html(res? "Yes": "No");
  100. if(res){
  101. Padomima.getMyMatch().then(function(res){
  102. matchhash = res;
  103. $("#matchhash").html(res);
  104. });
  105. Padomima.getMyStake().then(function(res){
  106. res = web3.fromWei(res);
  107. $("#stakeTxt").val(res);
  108. });
  109. Padomima.getMyMap().then(function(res){
  110. maphash = res;
  111. $("#maphash").html(res);
  112. });
  113. Padomima.getMyOpponent().then(function(res){
  114. opAccount = res;
  115. web3.eth.opponentAccount = res;
  116. $("#opponentHash").html(res);
  117. });
  118. }
  119. });
  120. }
  121. function updateMapTable(map,state){
  122. if(typeof state == "undefined"){
  123. state = {
  124. selected:{
  125. [web3.eth.defaultAccount]:[0,0,0,0,0,0],
  126. [web3.eth.opponentAccount]:[0,0,0,0,0,0]
  127. }
  128. };
  129. }
  130. state = web3.Game.applyStateRotation(state);
  131. var mapTable = $("#mapTable")[0];
  132. if(mapTable.hasChildNodes())
  133. mapTable.removeChild(mapTable.children[0]);
  134. var tbody = document.createElement("tbody");
  135. for(var i=0;i<6;i++){
  136. var tr = document.createElement("tr");
  137. if(state.selected[web3.eth.defaultAccount][i]){
  138. $(tr).addClass("green");
  139. }
  140. for (var j = 0; j < 6; j++) {
  141. var td = document.createElement("td");
  142. td.innerHTML = map[i][j];
  143. if(web3.Game.haveSelected(j)){
  144. $(td).addClass("green");
  145. }
  146. if(state.selected[web3.eth.opponentAccount][j]){
  147. $(td).addClass("red");
  148. }
  149. if(web3.Game.isMyNumber(i,j)){
  150. $(td).addClass("my-number");
  151. }
  152. if(web3.Game.isOpponentNumber(i,j)){
  153. $(td).addClass("op-number");
  154. }
  155. tr.appendChild(td);
  156. }
  157. tbody.appendChild(tr);
  158. }
  159. mapTable.appendChild(tbody);
  160. }
  161. /////////////////////
  162. //// CALCULATIONS ///
  163. /////////////////////
  164. // function hashToNumbers(hash){
  165. // var nums = [];
  166. // hash = hash.substr(2);
  167. // for(var i=0;i<32;i++){
  168. // var b = hash.substr(2*i, 2*i+2);
  169. // nums.push(web3.toDecimal('0x'+b));
  170. // }
  171. // return nums;
  172. // }
  173. // /////////////////////
  174. // function calculateMapArray(){
  175. // console.log("Calculating map array for map hash: " + maphash);
  176. // var first32Hash = maphash,
  177. // second32Hash = web3.sha3(first32Hash),
  178. // third32Hash = web3.sha3(second32Hash);
  179. // // Make hash to numbers
  180. // var numbers = hashToNumbers(first32Hash)
  181. // .concat(hashToNumbers(second32Hash))
  182. // .concat(hashToNumbers(third32Hash));
  183. // // init mapArray
  184. // var maparray = [];
  185. // for(var i=0;i<6;i++){
  186. // maparray.push([]);
  187. // for(var j=0;j<6;j++){
  188. // maparray[i][j] = i*6 + j + 1;
  189. // }
  190. // }
  191. // ///
  192. // /// helper local swapPosition
  193. // function swapPositions(a,b){
  194. // a = a % 36
  195. // ai = a % 6;
  196. // aj = parseInt(a / 6);
  197. // b = b % 36
  198. // bi = b % 6;
  199. // bj = parseInt(b / 6);
  200. // var temp = maparray[ai][aj];
  201. // maparray[ai][aj] = maparray[bi][bj];
  202. // maparray[bi][bj] = temp;
  203. // }
  204. // ///
  205. // for(var i=0;i<numbers.length;i++){
  206. // swapPositions(i, numbers[i]);
  207. // }
  208. // ////////////////////////////////
  209. // console.log(maparray);
  210. // ////////////////////////////////
  211. // return maparray;
  212. // }
  213. ///////////////////// CUSTOM NET ////
  214. function createMatch(stake){
  215. var createMatchData = Padomima.createMatch({value: web3.toWei(stake, 'ether'), gas: 200000});
  216. return createMatchData;
  217. }
  218. function joinMatch(stake, h){
  219. var joinMatchData = Padomima.joinMatch(h , {value: web3.toWei(stake, 'ether'), gas: 200000});
  220. return joinMatchData;
  221. }
  222. function getMatch(){
  223. Padomima.getMyMatch().then(function(res){
  224. console.log("MY Match Hash: " );
  225. console.log(res);
  226. });
  227. }
  228. function getMap(){
  229. Padomima.getMyMap().then(function(res){
  230. console.log("MY Map Hash: " );
  231. console.log(res);
  232. });
  233. }
  234. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  235. ///////////////////////////////////////////////////////////////////
  236. /////////// START GAME PHASE ///////////////////////////////////
  237. ///////////////////////////////////////////////////////////////////
  238. var dbname = web3.db.DBNAME = "CUSTOMDBFOR"+web3.eth.defaultAccount;
  239. function getDB(key){
  240. return web3.db.getString(dbname,key);
  241. }
  242. function getDBJSON(key){
  243. return JSON.parse(web3.db.getString(dbname,key));
  244. }
  245. function saveDBJSON(d){
  246. return;
  247. if(!web3.db.getString(dbname,"currentIndex"))
  248. web3.db.putString(dbname,"currentIndex","0");
  249. var cid = getDB("currentIndex");
  250. web3.db.putString(dbname, "Index" + cid, JSON.stringify(d));
  251. web3.db.putString(dbname, "currentIndex", ""+(parseInt(cid)+1) );
  252. }
  253. function saveDB(key, data){
  254. web3.db.putString(dbname, key, data);
  255. }
  256. function saveACK(data){
  257. // save ACK and mark it on UI
  258. saveDBJSON({
  259. who : web3.eth.defaultAccount,
  260. ack : data,
  261. opponent: opAccount
  262. });
  263. // update Current Game State to the next one because we have all the SIGNED information needed until here!
  264. return;
  265. }
  266. function saveOpponentMove(data){
  267. // save move and mark it on UI
  268. saveDBJSON({
  269. who : opAccount,
  270. ack : data
  271. });
  272. return;
  273. }
  274. function moveRecieved(data){
  275. console.log("Recieved Data from Game Channel:");
  276. console.log(data);
  277. if(web3.Game.performMove(data))
  278. return data;
  279. //web3.Game.communicateState();
  280. return false;
  281. }
  282. function stateHandler(){
  283. console.log("State changed!");
  284. console.log(web3.Game.getState());
  285. updateGameUI(web3.Game.getState());
  286. }
  287. function roundHandler(){
  288. console.log("Round changed!");
  289. updateGameUI(web3.Game.getState());
  290. }
  291. function startGame() {
  292. // body...
  293. $("#GameUI").removeClass("hidden");
  294. // Establish whisper connection //
  295. // web3.Lib.initWhisper(maphash.substr(2))
  296. // .then(function(w){
  297. // w.setFunction(moveRecieved);
  298. // web3.GWhisper = w;
  299. // });
  300. web3.NetLib.init();
  301. web3.NetLib.setChannel(maphash.substr(2));
  302. web3.NetLib.setSolo(web3.eth.opponentAccount);
  303. //web3.NetLib.addInterceptor(web3.Game.getStateInterceptor());
  304. web3.NetLib.setBasicInterceptors();
  305. web3.NetLib.addInterceptor(moveRecieved);
  306. web3.NetLib.startListening();
  307. web3.Game.init(maphash);
  308. web3.Game.setOnStateChange(stateHandler);
  309. web3.Game.setOnRoundChange(roundHandler);
  310. Padomima.getMapRotation().then(function(res){
  311. web3.Game.setMapRotation(res);
  312. updateMapTable(web3.Game.getMapArray());
  313. web3.Game.loadFromDB();
  314. updateGameUI(web3.Game.getState());
  315. });
  316. }
  317. function sendSelectMove(){
  318. var mycol = parseInt($("#columnForMe").val())-1;
  319. var opcol = parseInt($("#columnForOp").val())-1;
  320. var move = web3.Game.createSelectMove(mycol,opcol);
  321. web3.Game.performMove(move.move);
  322. web3.NetLib.sendPacketWaitForVerification(move.move);
  323. web3.Game.saveProof(move.proof.data.selectIndex % 4, move.proof);
  324. // var move = web3.sha3(''+mycolR).substr(2) + "+" + web3.sha3(''+opcolR).substr(2);
  325. // var moveSignature = web3.Lib.signData(web3.eth.defaultAccount, move);
  326. // console.log("Move Signature : ");
  327. // console.log(moveSignature);
  328. // console.log("Verifying locally...");
  329. // var ver = web3.Lib.verifySignature(web3.eth.defaultAccount, moveSignature);
  330. // console.log(ver);
  331. // Send through Whisper
  332. //web3.GWhisper.send({ who: web3.eth.defaultAccount, signature : moveSignature })
  333. }
  334. function sendBetMove(){
  335. var am = parseInt($("#amount").val());
  336. var move = web3.Game.createBetMove(am);
  337. if(web3.Game.performMove(move))
  338. web3.NetLib.sendPacketWaitForVerification(move);
  339. }
  340. function sendCallMove(){
  341. var move = web3.Game.createCallMove();
  342. if(web3.Game.performMove(move))
  343. web3.NetLib.sendPacketWaitForVerification(move);
  344. }
  345. function sendFoldMove(){
  346. var move = web3.Game.createFoldMove();
  347. if(web3.Game.performMove(move))
  348. web3.NetLib.sendPacketWaitForVerification(move);
  349. }
  350. function sendProofMove(){
  351. var proofnum = parseInt($("#proofCol").val());
  352. var move = web3.Game.getProofMove(proofnum);
  353. if(web3.Game.performMove(move))
  354. web3.NetLib.sendPacketWaitForVerification(move);
  355. }
  356. /////////////////////////////////////////////////////////////////////////////
  357. /////////////// GAME HELPERS /////////////////////////////////////////
  358. ///////////////////////////////////////////////////////////////////////
  359. function findRandomBigNumber(num){
  360. var randomNumber = Math.floor(10000000000 + Math.random() * 90000000000);
  361. while(randomNumber % 6 != num){
  362. randomNumber++;
  363. }
  364. // console.log("Random Big Number for : " + num);
  365. // console.log(randomNumber);
  366. return randomNumber;
  367. }
  368. function printMoveStack(){
  369. console.log("---- Move Stack --------");
  370. var cid = getDB("currentIndex");
  371. for( var i = 0; i < cid; i ++ ){
  372. console.log(getDBJSON("Index" + i));
  373. }
  374. console.log("------------------------");
  375. }