tomitankChess - New JavaScript engine

Discussion of anything and everything relating to chess playing software and machines.

Moderators: hgm, Harvey Williamson, bob

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
tomitank
Posts: 166
Joined: Sat Mar 04, 2017 11:24 am
Location: Hungary

Re: tomitankChess - New JavaScript engine

Post by tomitank » Thu Sep 21, 2017 10:33 am

hgm wrote:Did you use some compaction program on it?

Most variable names also seem automatically generated, like _0xff55x7c. Did you originally write it in another language, and then decompile the executable to JavaScript?
No.
I'm use this site:
http://www.javascriptobfuscator.com/Jav ... cator.aspx

I just wanted to share a game, not the source code, but your work is incredible :)
(I know the "github" is not for this.)
First, i would like tune some search parameter.
I think this will be the strongest JavaScript chess engine in the world. (without Enscripten and V8)
Maybe already so. (I hope.)
This will work in my mobile application.
I will share the next version with source code.

User avatar
hgm
Posts: 22274
Joined: Fri Mar 10, 2006 9:06 am
Location: Amsterdam
Full name: H G Muller
Contact:

Re: tomitankChess - New JavaScript engine

Post by hgm » Thu Sep 21, 2017 8:51 pm

OK, I see. It doesn't do a very good job, because it leaves the routine names unobfuscated. (Perhaps it must, to keep it possible to call them from another file.) When one knows that the routine I lifted out is a Quiescence Search, it becomes quite trivial to guess the fuction of all the local variables, especially when you can see which are assigned things like Evaluation(), currentPlayer^8, isCheck()... But as it was not your intetion to publish the code, I won't show the completely de-obfuscated version of Quiescece() I made in about 2 minutes.

I was not so much interested in how exactly your code worked, as whether one could use things like recursion, local variables, global arrays... So I have already seen enough to conclude that JavaScript is almost exactly the same as C, with just a few tiny differeces to the syntax. So that means JavaScript doesn't pose any new problems, which is good news for me.

tomitank
Posts: 166
Joined: Sat Mar 04, 2017 11:24 am
Location: Hungary

Re: tomitankChess - New JavaScript engine

Post by tomitank » Thu Sep 21, 2017 10:09 pm

But as it was not your intetion to publish the code
I did not even assume.I was just kidding : )

This encrypt method is not perfect.

As I said: If everything is ready, I will publish it ; )

I really respect you! I hope you didn't misunderstand.

Yes! JavaScript is very similar, but very slow. (no 64 bit integer, no macros, no memori management etc..)

User avatar
hgm
Posts: 22274
Joined: Fri Mar 10, 2006 9:06 am
Location: Amsterdam
Full name: H G Muller
Contact:

Re: tomitankChess - New JavaScript engine

Post by hgm » Fri Sep 22, 2017 7:52 am

I also took a peek as to how you did your hash table, so see if the entries are structs as I would do in C. But I see you are using arrays for those, and even arrays that are 'indexed' bij character strings.

Code: Select all

function HashEntry(_0xff55x7c,_0xff55x80,_0xff55x82,_0xff55x87,_0xff55x88,_0xff55x7f){
  this["move"]= _0xff55x7c;
  this["flag"]= _0xff55x82;
  this["depth"]= _0xff55x87;
  this["score"]= _0xff55x80;
  this["hashKeyLow"]= _0xff55x88;
  this["hashKeyHigh"]= _0xff55x7f
}
Doesn't this cause an incredible slowdown? It must mean that every HashEntry is in fact a tiny hash table in itself, and that to store the data items it must calculate a hash key from strings like "hashKeyLow" before it can know where the data was stored. (Or worse, do a linear search.) I also wonder if this doesn't blow up the side of the HashEntry enormously, e.g. because it also stores the strings "move", "flag" etc. with each of them. Wouldn't it be much faster to just use "this[0] = ...", "this[1] = ..."?

The obfuscator seems to make this even far worse, because it puts the strings in an array, from which it has to be fetched first, so that in the code above it does not even look like a constant 'index' (which could be calculated at compile time), but becomes a unknow variable, not even known to be a string. The array _0x1b7c could be made to contain any data type, so the decision to use an array or hash table must be taken at run time for every HashEntry that is written:

Code: Select all

function HashEntry(_0xff55x7c,_0xff55x80,_0xff55x82,_0xff55x87,_0xff55x88,_0xff55x7f){
  this[_0x1b7c[29]]= _0xff55x7c;
  this[_0x1b7c[30]]= _0xff55x82;
  this[_0x1b7c[31]]= _0xff55x87;
  this[_0x1b7c[32]]= _0xff55x80;
  this[_0x1b7c[33]]= _0xff55x88;
  this[_0x1b7c[34]]= _0xff55x7f
}
I also wonder why you create a new HashEntry every time you do a HashStore. Why not just overwrite the data in the existing one. Does't this waste enormous amounts of memory?

Or am I completely misunderstanding how JavaScript works?

SzG
Posts: 2447
Joined: Fri Mar 10, 2006 6:20 am
Location: Szentendre, Hungary

Re: tomitankChess - New JavaScript engine

Post by SzG » Fri Sep 22, 2017 8:30 am

tomitank wrote:tomitankChess 1.4 (case sensitive) :D

This run on 32 and 64 bit.
In a 64-bit system what decides if it runs as 64-bit or 32-bit? Is it faster in a 64-bit environment?
Gabor Szots

CCRL testing group

tomitank
Posts: 166
Joined: Sat Mar 04, 2017 11:24 am
Location: Hungary

Re: tomitankChess - New JavaScript engine

Post by tomitank » Fri Sep 22, 2017 10:17 am

I use "Always Replace" strategy.

Here is the source code:

Code: Select all

var HASHENTRIES		= &#40;28 << 20&#41; / 14; // Hashtabla merete 28 MB / 1 Hash merete &#40;14 Byte&#41;
var HASHMASK		= HASHENTRIES - 1; // Hashtabla maszk, csak ketto hatvanya lehet & MASK

Code: Select all

	function StoreHashMove&#40;move, score, flags, depth&#41; &#123;

		if &#40;score > ISMATE&#41; &#123; // Pontszam fixalasa
			score += boardPly;
		&#125; else if &#40;score < -ISMATE&#41; &#123; // Pontszam fixalasa
			score -= boardPly;
		&#125;

		brd_HashTable&#91;brd_hashKeyLow & HASHMASK&#93; = new HashEntry&#40;move, score, flags, depth, brd_hashKeyLow, brd_hashKeyHigh&#41;; // 108 bit /14 Byte/
	&#125;


	function HashEntry&#40;move, score, flags, depth, hashLow, hashHigh&#41; &#123;
		this.move			= move; // 20 bit
		this.flags			= flags; // 2 bit
		this.depth			= depth; // 7 bit
		this.score			= score; // 15 bit
		this.hashKeyLow		= hashLow; // 32 bit
		this.hashKeyHigh	= hashHigh; // 32 bit
	&#125;
I use 1 array -> it's called: brd_HashTable
The entries is Objects, not arrays, and not strings.

It could have been like this:

Code: Select all

brd_HashTable&#91;brd_hashKeyLow & HASHMASK&#93; = &#123;
	move &#58; move,
	flags &#58; flags,
	depth &#58; depth,
	score &#58; score,
	hashKeyLow &#58; brd_hashKeyLow,
	hashKeyHigh&#58; brd_hashKeyHigh
&#125;;
but in most browsers with "Object prototype" is a bit faster.
function HashEntry is my prototype.
So, this is not string, but also object in array.
(It's difficult because browser-dependent is the speed.)
I saw this method in garboChess.js

So you can refer to it:

Code: Select all

brd_HashTable&#91;brd_hashKeyLow & HASHMASK&#93;.score
brd_HashTable&#91;brd_hashKeyLow & HASHMASK&#93;.flags
brd_HashTable&#91;brd_hashKeyLow & HASHMASK&#93;.depth
In C would look like this(but this is different):

Code: Select all

brd_HashTable&#91;brd_hashKeyLow & HASHMASK&#93;->score
brd_HashTable&#91;brd_hashKeyLow & HASHMASK&#93;->flags
brd_HashTable&#91;brd_hashKeyLow & HASHMASK&#93;->depth
Very important:
so the maximal hash size is 28mb (currently).
If this is bigger, than some mobile browser crashes.
In a UCI i would like with bigger hash...
And again: JavaScript chess engine is difficult because browser-dependent is the speed.

tomitank
Posts: 166
Joined: Sat Mar 04, 2017 11:24 am
Location: Hungary

Re: tomitankChess - New JavaScript engine

Post by tomitank » Fri Sep 22, 2017 10:31 am

Hi Gabor!

Javascript doesn't have 64 bit integers.
"Before a bitwise operation is performed, JavaScript converts numbers to 32 bits signed integers."

Please read this: http://talkchess.com/forum/viewtopic.php?t=65198

So this runs very similar.(slow)
This is not C..
It's hard to make a strong engine.

This will work in my mobile application. (This is a cordova project)

More on: https://cordova.apache.org/

I want to use my own engine. (Not the Stockfish-js Emscript version)

Currently run with my older engine:
https://play.google.com/store/apps/deta ... y.hu&hl=hu
https://itunes.apple.com/hu/app/sakk-in ... 54415?mt=8

In a few days, the automatic English language support comes. The "UI" is also self-made product.

User avatar
hgm
Posts: 22274
Joined: Fri Mar 10, 2006 9:06 am
Location: Amsterdam
Full name: H G Muller
Contact:

Re: tomitankChess - New JavaScript engine

Post by hgm » Fri Sep 22, 2017 10:55 am

Thanks very much for the explanation. What you show as original source code could ideed be efficient. As you can see the obfuscator completely destroys this. So I wonder how much of a slowdown the obfuscation causes.

You seem to assume the size of the hash entry is 14 byte. But how should the JavaScript know that any of the this.depth, this.flags... can be smaller than a normal 32-bit integer? I would have expected a size of 6x4 = 24 byte fir the data you store. And the brd_HashTable array probably contains a pointer (4 or 8 additional bytes?) to the object itself.

I don't know if even storing a simple integer would not require more than 4 byte in JavaScript, because it has to remember somewhere that it is an integer too (as JavaScript allows it to be anything else).

User avatar
Evert
Posts: 2898
Joined: Fri Jan 21, 2011 11:42 pm
Location: NL
Contact:

Re: tomitankChess - New JavaScript engine

Post by Evert » Fri Sep 22, 2017 11:26 am

hgm wrote:Thanks very much for the explanation. What you show as original source code could ideed be efficient. As you can see the obfuscator completely destroys this. So I wonder how much of a slowdown the obfuscation causes.
None, if my memory is correct. From what I remember 'var["key"] = value' and 'var.key = value' are equivalent constructs in JavaScript (so it may look like a struct, but it's really a hash). That may even be the case for arrays, but don't take my word for it. I looked into it a while back to see if it would be doable to port SjaakII to JavaScript, but I didn't do much with it in the end.
Long story short: JavaScript was not meant to be used for high performance computing...

tomitank
Posts: 166
Joined: Sat Mar 04, 2017 11:24 am
Location: Hungary

Re: tomitankChess - New JavaScript engine

Post by tomitank » Fri Sep 22, 2017 11:59 am

Evert wrote: From what I remember 'var["key"] = value' and 'var.key = value' are equivalent constructs in JavaScript.
Almost. The non multiple arrays bit faster in JavaScript.
Eg: array declaration mode in JavaScript is very important for speed.
https://stackoverflow.com/questions/931 ... ascript-ar

It's tricky, but this depends on the browser. Node.js can give you another result. (Unfortunately.)
Evert wrote: Long story short: JavaScript was not meant to be used for high performance computing...
Yes. I hope my engine will be around 2500 Elo (maybe 2600).
Of course with pure JavaScript.

Post Reply