PtokaX forum

Archive => Archived 4.0 boards => Request for Lua 4 scripts => Topic started by: exlepra on 18 August, 2004, 11:37:28

Title: Jumblefever 2 'mod'
Post by: exlepra on 18 August, 2004, 11:37:28
Hi, I use jumblefever 2, it is working properly ( thx RabidWombat) , but words are very often repeated even with big dictionary. How can it be modified to not allow repeat only after a specified number of question in the game?


I was thinking of storing the used random numbers " random(iFileSize)-1) " somewhere and compare the newly generated random values to them, if match generate a new one unless the stored numbers amount is equal to the iFilesize (or any preset value less than iFilesize). Then the "buffer" could be emptyed. This way repeat would be posible only after all words in the dictionary are used (or after the "buffer" reaches the preset value).

But im very untalented programmer :)
Title:
Post by: plop on 18 August, 2004, 21:21:31
check version 2 of my kickbattle.
you can find how 2 make it use all words, and after that start all over again.

plop
Title:
Post by: NotRabidWombat on 19 August, 2004, 01:40:01
QuoteHi, I use jumblefever 2, it is working properly ( thx RabidWombat) , but words are very often repeated even with big dictionary. How can it be modified to not allow repeat only after a specified number of question in the game?
1) Are you using your own dictionary file? If so, how many words does it include? Have you checked it for duplicates
2) "very often repeated" - define this. Obviously if there are n words, every words has the probabitity of being selected every time a word is selected (1/n). Since these selections are independent, the probability of selected the same word twice is directly proportional to the number of times a word is selected (x/n). With a standard distribution of random numbers, this should result in very few words being repeated until n words have been selected. The english dictionary I used for my hub had very few repeats over the course of an entire year (playing occuring maybe 12-16 hours a day).

QuoteI was thinking of storing the used random numbers " random(iFileSize)-1) " somewhere and compare the newly generated random values to them, if match generate a new one unless the stored numbers amount is equal to the iFilesize (or any preset value less than iFilesize). Then the "buffer" could be emptyed. This way repeat would be posible only after all words in the dictionary are used (or after the "buffer" reaches the preset value).

But im very untalented programmer :)
That method is a very bad idea. The range would stay static while the number of words decreased. This would result in the probabilty of selecting a "non-selected" word would decrease. In other words, as time goes on the time to complete the word selection will increase dramatically. It could possibly cause congestion with hub communication.
The best method would be to remove the words from the list as you select them (algorithm would perform at O(n) ). Then the range of the table would always be the same as the number of words.

But to tell you the truth, I think it's PBKAC ;-)

-NotRabidWombat
Title:
Post by: NotRabidWombat on 19 August, 2004, 05:55:27
I have reviewed the souce code of Jumble Fever. I rediscovered the problem I encountered when originally designing the code. There is no API in Lua 4 to grab the time since some arbitrary date (in a single number format). This is solved in Lua 5.0 with the os.time() function.

To compensate for the lack of this feature, I seed the random number generator in two locations with clock() which is the number of seconds of processing time the script  has been running. There are very few places to seed the random number generator this way. Obviously this isn't the best way to get random data, but it was the most obvious and easiest at the time.

Anyway, onto the possible solution.

Comment the two lines that contain: randomseed(....

Add:
function getTime()
local iRet;

execute("echo WScript.Echo((new Date()).getTime()); > ~tmp.js &&" ..
" cscript //NOLOGO ~tmp.js > ~time.tmp");

hFile = openfile("~time.tmp", "r");
iRet = read(hFile, "*n");

closefile(hFile);

remove("~tmp.js");
remove("~time.tmp");

return iRet;
end
A lot of work just to get the number of milliseconds since Jan 1, 1970. :-\ Fortunetly, you only have to do this every time you restart the script.

So put the following in main().
randomseed(getTime());

According to http://lua-users.org/wiki/MathLibraryTutorial you should also call random a few times to start getting "real" random numbers. I'm not sure how legitimate this claim actually is. Remember that wiki is for Lua 5, so the function call would be "random()" not "math.random()".

Note to other devs: This is will not return an accurate time since time will pass when reading the file. It is only effective at getting a number for seeding a random number generator.

-NotRabidWombat
Title:
Post by: plop on 19 August, 2004, 07:05:31
i had this problem on my downtime script for bcdc.
on nearly 1/3 of the time it showed the same time.
solved it by grabbing the time and removing the : from it and converting it 2 a number 2 feed randomseed.
public kick battle removes all the used words from the table, when there aren't enough words left it rebuilds the table.

plop
Title:
Post by: exlepra on 19 August, 2004, 13:20:20
I have an own 300 words dic file plus a 10 words file for random testing.

Thx for the random info, but thats maybe not exactly what im looking for, because in this case repeats are still possible.

If I understood the script properly the iFilesize is the file lenght in bytes, so by using random(iFilesize) longer words/expressions have bigger chance.


whats pbkac?
Title:
Post by: NotRabidWombat on 19 August, 2004, 13:38:50
Plop,

The table method would not good for the typically usage of Jumble, a dictionary file with 20,000+ words.

Also, BCDC uses Lua 5.0 so you don't have to convert date to a usefull time number. Just use os.time() :-D

exlepra,

PBKAC - Problem Between Keyboard And Chair

The small dictionary file is what I expected. Jumble was designed with larger files in mind (since it makes a more interesting Jumble game). That is why I chose file seeking over adding the words to a table.

"If I understood the script properly the iFilesize is the file lenght in bytes, so by using random(iFilesize) longer words/expressions have bigger chance."

You are _almost_ correct in your assumption. I actually seek to a position in the file, read to the end of that line and then read the next line (I didn't want to seek backwards). So words with larger words preceeding them have a higher probability of being selected. However, this is neglible if you use a large dictionary file :-)

Anyway, even if you remove repeats from the list of 300,  the game will be boring in a matter of hours (10 to go through the list once). I don't see any point to supporting such a small dictionary file.

-NotRabidWombat
Title:
Post by: exlepra on 19 August, 2004, 15:13:27
Ok, so I should not expect the first word in the dict. to be appeared in the game. :)
Is there a command which gives the number of lines in a file back?
Title:
Post by: NotRabidWombat on 19 August, 2004, 16:58:37
"Ok, so I should not expect the first word in the dict. to be appeared in the game. :) "

Yes, I thought I made a note with the package instructing the  installer to add the first line twice to the dictionary file. It was a while ago.

"Is there a command which gives the number of lines in a file back?"

DOS: find /C /V "" C:\test.cpp

Lua:
function countLines(sFileName)
   local count = 0;

   hFile = openfile(sFileName, "r");

   assert(hFile, "File must exist!");

   while ( read(hFile) ) do
      count = count + 1;
   end

   return count;
end
I just whipped this up because I'm at work. Might have problems in it. Concept is there though.

-NotRabidWombat