Ludii Forum
Generate Random Game - Printable Version

+- Ludii Forum (https://ludii.games/forums)
+-- Forum: Questions (https://ludii.games/forums/forumdisplay.php?fid=13)
+--- Forum: About Ludii (https://ludii.games/forums/forumdisplay.php?fid=14)
+--- Thread: Generate Random Game (/showthread.php?tid=395)



Generate Random Game - RogerCooper - 01-27-2021

What does "Generate Random Game" do?


RE: Generate Random Game - cambolbro - 01-27-2021

Hi,

It literally generates a random game, i.e. it assembles random collections of ludemes according to the grammar until it finds a combination that makes a "playable" game. A game is deemed playable if it:
1. Conforms to the grammar.
2. Compiles without error.
3. Creates its Game object without error.
4. Allows each player to move at least once.

This doesn't mean that the game is any good! We've found that about 1 in 10,000 random games deemed "playable" are actually what humans would deem to be a proper game. Of those, only a very small number (one in a million?) would actually be interesting games worth playing.

So random game generation is mostly for testing and debugging purposes; there's nothing like a few thousand randomly assembled rule sets to test your code! To generate interesting games, it's best to start with existing games and evolve them.

Regards,
Cameron


RE: Generate Random Game - RogerCooper - 01-27-2021

(01-27-2021, 07:23 AM)cambolbro Wrote: It literally generates a random game, i.e. it assembles random collections of ludemes according to the grammar until it finds a combination that makes a "playable" game. A game is deemed playable if it:
Where does it put this random game?


RE: Generate Random Game - cambolbro - 01-27-2021

It just loads the current game in the app. You can copy and paste the description from the Ludeme panel when it does.

Note that it can take a while to find a "playable" game.


RE: Generate Random Game - xenos1984 - 01-27-2021

Hi Cameron,

is there a way to abort the game generation, other than killing the app? It seems that the app freezes while it is working.

By the way, I didn't find it in the Ludeme panel, but in the console output (I run Ludii from the command line) along with some Java exceptions:

Code:
Terminal constant 'false' is lowercase.
Terminal constant 'false' is lowercase.
Terminal constant 'false' is lowercase.
Terminal constant 'true' is lowercase.
- Warning: Terminal constant 'false' is lowercase.
- Warning: Terminal constant 'true' is lowercase.
Terminal constant 'false' is lowercase.
Terminal constant 'false' is lowercase.
Terminal constant 'false' is lowercase.
Terminal constant 'true' is lowercase.
Exception during game creation: java.lang.NullPointerException
- Warning: Terminal constant 'false' is lowercase.
- Warning: Terminal constant 'true' is lowercase.
language.compiler.exceptions.CompilerException: Exception during game creation: java.lang.NullPointerException
        at language.compiler.Compiler.compile(Compiler.java:96)
        at language.compiler.Compiler.compileTest(Compiler.java:59)
        at approaches.random.Generator.testGames(Generator.java:792)
        at app.menu.MainMenuFunctions.checkActionsPerformed(MainMenuFunctions.java:918)
        at app.DesktopApp.actionPerformed(DesktopApp.java:301)
        at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
        at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
        at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
        at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
        at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:369)
        at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1020)
        at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1064)
        at java.desktop/java.awt.Component.processMouseEvent(Component.java:6636)
        at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
        at java.desktop/java.awt.Component.processEvent(Component.java:6401)
        at java.desktop/java.awt.Container.processEvent(Container.java:2263)
        at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5012)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
        at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4919)
        at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4548)
        at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4489)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
        at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2764)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: language.compiler.exceptions.CreationErrorWithMessageException
        at language.compiler.Compiler.compileActual(Compiler.java:215)
        at language.compiler.Compiler.compile(Compiler.java:90)
        ... 41 more
java.io.FileNotFoundException: /home/mhohmann/../Common/res/lud/test/buggy/uncompilable/Anon.lud (No such file or directory)
        at java.base/java.io.FileOutputStream.open0(Native Method)
        at java.base/java.io.FileOutputStream.open(FileOutputStream.java:291)
        at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:234)
        at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:123)
        at java.base/java.io.PrintWriter.<init>(PrintWriter.java:200)
        at main.FileHandling.saveStringToFile(FileHandling.java:730)
        at approaches.random.Generator.testGames(Generator.java:810)
        at app.menu.MainMenuFunctions.checkActionsPerformed(MainMenuFunctions.java:918)
        at app.DesktopApp.actionPerformed(DesktopApp.java:301)
        at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
        at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
        at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
        at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
        at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:369)
        at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1020)
        at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1064)
        at java.desktop/java.awt.Component.processMouseEvent(Component.java:6636)
        at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
        at java.desktop/java.awt.Component.processEvent(Component.java:6401)
        at java.desktop/java.awt.Container.processEvent(Container.java:2263)
        at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5012)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
        at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4919)
        at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4548)
        at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4489)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
        at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2764)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

===========================================
1 random games generated in 0.002s:
1 valid (100.0%).
1 parse (100.0%).
0 compile (0.0%).
0 functional (0.0%).
0 playable (0.0%).


---------------------------------
Game 0:
(match " "
    (players { (player (directions { BLL Forward Rightwards } of:All)) })
    (games (subgame " " next:(score (player -3))))
    (end { (forEach if:false (result Team4 Abandon)) })
)

Terminal constant 'false' is lowercase.
java.io.FileNotFoundException: /home/mhohmann/../Common/res/lud/test/buggy/unparsable/Anon.lud (No such file or directory)
        at java.base/java.io.FileOutputStream.open0(Native Method)
        at java.base/java.io.FileOutputStream.open(FileOutputStream.java:291)
        at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:234)
        at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:123)
        at java.base/java.io.PrintWriter.<init>(PrintWriter.java:200)
        at main.FileHandling.saveStringToFile(FileHandling.java:730)
        at approaches.random.Generator.testGames(Generator.java:771)
        at app.menu.MainMenuFunctions.checkActionsPerformed(MainMenuFunctions.java:918)
        at app.DesktopApp.actionPerformed(DesktopApp.java:301)
        at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
        at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
        at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
        at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
        at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:369)
        at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1020)
        at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1064)
        at java.desktop/java.awt.Component.processMouseEvent(Component.java:6636)
        at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
        at java.desktop/java.awt.Component.processEvent(Component.java:6401)
        at java.desktop/java.awt.Container.processEvent(Container.java:2263)
        at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5012)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
        at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4919)
        at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4548)
        at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4489)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
        at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2764)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

===========================================
1 random games generated in 0.001s:
1 valid (100.0%).
0 parse (0.0%).
0 compile (0.0%).
0 functional (0.0%).
0 playable (0.0%).


---------------------------------
Game 0:
(match " "
    (games { (subgame " ") (subgame " ") (subgame " ") })
    (end
        {
            (forEach if:false (byScore))
            (if true)
            (if false)
            (forEach if:false (result Team14 Win))
        }
    )
)

Then it stopped, after many more such lines, but with no game it considered playable.

Best,
Manuel


RE: Generate Random Game - cambolbro - 01-28-2021

Hi,

No, you have to kill the app. We can move the process to a background thread that prints the game when ready, but ultimately we'll have game generation dialogs that give more control over the generation process.

Note that it can take a long time to find a "playable" randomly generated game, depending on how lucky you are.

In the meantime I'll move "Generate Random Game" to the Developer menu until it's ready for public consumption.

Regards,
Cameron


RE: Generate Random Game - slimy_asparagus - 01-28-2021

(01-28-2021, 03:18 PM)cambolbro Wrote: .....ultimately we'll have game generation dialogs that give more control over the generation process.

I am wondering what sort of control you are thinking of here. Two obvious things that occur to me are:

1. Starting from a particular game.
2. Allowing certain parts of a game to be kept constant.

(01-27-2021, 07:23 AM)cambolbro Wrote: We've found that about 1 in 10,000 random games deemed "playable" are actually what humans would deem to be a proper game.
I am curious how you arrived at that figure. It sounds like the most boring way of playing games! And I wonder if that filter is not too lax.

Maybe if you added the following criteria:

* A game that goes on for at least X moves or of the trials that end in less than X moves, each player wins at least Y% of the time.

I think that would filter out a lot of degenerate games.


RE: Generate Random Game - cambolbro - 02-01-2021

Hi,

Quote:I am wondering what sort of control you are thinking of here.

Exact format to be decided, but one approach will be through a "reconstruction syntax" that lets the user annotate degrees of freedom directly in the .lud descriptions. This will be the primary mechanism for generating the reconstructions that will be a major part of the DLP. 

Quote:I am curious how you arrived at that figure.

By running the random game generator several times and observing how often it threw up a "playable" game.

Quote:Maybe if you added the following criteria:

* A game that goes on for at least X moves or of the trials that end in less than X moves, each player wins at least Y% of the time.

I think that would filter out a lot of degenerate games.

We've already implemented the equivalents of those metrics (see the "Game Evaluation" dialog) but they're not very useful for random game generation. You'd be waiting a looong time between rule sets that satisfy this test.

Regards,
Cameron