Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fsx version to the dojo #6

Merged
merged 5 commits into from
Mar 22, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 33 additions & 31 deletions Dojo/Canopy2048/Canopy2048.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,60 +37,62 @@
<DocumentationFile>bin\Release\Canopy2048.XML</DocumentationFile>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '11.0'">
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" />
<ItemGroup>
<Compile Include="Core.fs" />
<Compile Include="Game.fs" />
<Compile Include="Interactions.fs" />
<Compile Include="Program.fs" />
<None Include="App.config" />
<Content Include="packages.config" />
<None Include="Script.fsx" />
</ItemGroup>
<ItemGroup>
<Reference Include="canopy">
<HintPath>packages\canopy.0.9.8\lib\canopy.dll</HintPath>
<HintPath>packages\canopy.0.9.22\lib\canopy.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Reference Include="FSharp.Core">
<HintPath>packages\FSharp.Core.3.0.2\lib\net40\FSharp.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="Newtonsoft.Json">
<HintPath>packages\Newtonsoft.Json.5.0.1\lib\net40\Newtonsoft.Json.dll</HintPath>
<HintPath>packages\Newtonsoft.Json.6.0.1\lib\net40\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SizSelCsZzz">
<HintPath>packages\SizSelCsZzz.0.3.35.0\lib\SizSelCsZzz.dll</HintPath>
<HintPath>packages\SizSelCsZzz.0.3.36.0\lib\SizSelCsZzz.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Numerics" />
<Reference Include="WebDriver">
<HintPath>packages\Selenium.WebDriver.2.41.0\lib\net40\WebDriver.dll</HintPath>
<HintPath>packages\Selenium.WebDriver.2.45.0\lib\net40\WebDriver.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="WebDriver.Support">
<HintPath>packages\Selenium.Support.2.41.0\lib\net40\WebDriver.Support.dll</HintPath>
<HintPath>packages\Selenium.Support.2.45.0\lib\net40\WebDriver.Support.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Core.fs" />
<Compile Include="Game.fs" />
<Compile Include="Interactions.fs" />
<Compile Include="Program.fs" />
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '11.0'">
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
Expand Down
17 changes: 13 additions & 4 deletions Dojo/Canopy2048/Interactions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@ open runner

module Interactions =

let lost () =
match someElement ".game-message.game-over" with
let lostSelector = css ".game-message.game-over"
let winSelector = css ".game-message.game-won"
let gameOverSelector = css ".game-message.game-won, .game-message.game-over"

let lost () =
match someElement <| lostSelector with
| None -> false
| Some(_) -> true

let won () =
match someElement <| winSelector with
| None -> false
| Some(_) -> true

let won () =
match someElement ".game-message.game-won" with
let gameEnded () =
match someElement <| gameOverSelector with
| None -> false
| Some(_) -> true

Expand Down
131 changes: 131 additions & 0 deletions Dojo/Canopy2048/Script.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
(*
The goal of this dojo is to learn the basics of
the F# Canopy web testing framework, written
by Chris Holt (www.twitter.com/lefthandedgoat),
using it to drive the game "2048".

The dojo is setup as as series of tasks,
embedded in this file. It starts with simple
examples using Canopy to interact with the
game web page, and progressively builds up
to writing an automated bot to play the game.

Have fun! Any feedback is highly appreciated,
either on the GitHub repository itself:
https://github.com/c4fsharp/Dojo-Canopy-2048
or via Twitter on @c4fsharp.

And if you enjoy it, feel free to tweet about it,
using the hashtag #fsharp!
*)


(*
Task 0: play a game of 2048.
If you have never seen it before, run it here:
http://gabrielecirulli.github.io/2048/

Also, the documentation for Canopy is here:
http://lefthandedgoat.github.io/canopy/actions.html
*)
#r @"packages\Selenium.WebDriver.2.45.0\lib\net40\WebDriver.dll"
#r @"packages\Selenium.Support.2.45.0\lib\net40\WebDriver.Support.dll"
#r @"packages\canopy.0.9.22\lib\canopy.dll"
#load "Core.fs"

open Canopy2048
#load "Game.fs"
#load "Interactions.fs"

open canopy
open runner
open System

canopy.configuration.optimizeBySkippingIFrameCheck <- true
canopy.configuration.optimizeByDisablingCoverageReport <- true

(*
Task 1: start your browser.
depending on what browser you prefer,
you may have to install a browser driver
on your machine.
*)



(*
Task 2: open the game url.
*)



(*
Task 3: play up, left, down, right.
*)



(*
Task 4: retrieve the score.
Check the page and look for the
appropriate css tag.
*)



(*
Task 5: play a random game.
Write a bot that will randomly play
up, left, down or right at each turn.
A loop based on recursion is probably
a good way to go!
*)



(*
Task 6: terminate!
Improve your bot - it would be nice if
the bot stopped playing when the game
is either lost or won!
The module Interactions contains 2 handy
functions that will identify these 2
situations, lost () and won ().
*)



(*
Task 7: gimme some brains!
Let's give the bot a minimum of brains.
Instead of playing randomly, at each
turn, let's analyze each of the 4 possible
moves, and pick the move that gives you
the best one-shot score.
The module Interactions contains a function
that will extract the State of the game
from the page; it is represented as a Map,
containing non-empty cells.
The keys are of type Pos, of the form
{ Row = 1; Column = 2 }, the values are the
integer number in the cell.
The module Game contains a function execute,
which takes in a State and a Move, and
returns a tuple:
* the score increase of the move,
* the State after the move.
*)



(*
Task 8: go for it!
Now that you have a dumb bot, your turn
to experiment and see if you can make that bot
smarter!
*)



// Just to make sure the test function
// ends properly.()
11 changes: 6 additions & 5 deletions Dojo/Canopy2048/packages.config
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="canopy" version="0.9.8" targetFramework="net40" />
<package id="Newtonsoft.Json" version="5.0.1" targetFramework="net40" />
<package id="Selenium.Support" version="2.41.0" targetFramework="net40" />
<package id="Selenium.WebDriver" version="2.41.0" targetFramework="net40" />
<package id="SizSelCsZzz" version="0.3.35.0" targetFramework="net40" />
<package id="canopy" version="0.9.22" targetFramework="net40" />
<package id="FSharp.Core" version="3.0.2" targetFramework="net40" />
<package id="Newtonsoft.Json" version="6.0.1" targetFramework="net40" />
<package id="Selenium.Support" version="2.45.0" targetFramework="net40" />
<package id="Selenium.WebDriver" version="2.45.0" targetFramework="net40" />
<package id="SizSelCsZzz" version="0.3.36.0" targetFramework="net40" />
</packages>
2 changes: 1 addition & 1 deletion Organizer/Organizer-Notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The goal of the Dojo is two-fold:
* provide a basic introduction to [Canopy][canopy], a F# web UI testing library,
* write a game loop to automatically play the game of [2048][2048], against the actual game page.

The Dojo itself doesn't require much in terms of introduction. Play a game of 2048 live to demonstrate the rules (4 actions are possible, press up/down/left/right, adjacent tiles of same value get collapsed into one, the goal is to get a 2048 tile) - and then direct people to the file "Program.fs", which is a console app containing a set of Tasks leading to a basic working bot.
The Dojo itself doesn't require much in terms of introduction. Play a game of 2048 live to demonstrate the rules (4 actions are possible, press up/down/left/right, adjacent tiles of same value get collapsed into one, the goal is to get a 2048 tile) - and then direct people to the file `Program.fs`, which is a console app containing a set of Tasks leading to a basic working bot. For people who prefer to work with F# interactive, you can direct them to `Script.fsx`.

The dojo progresses from:
* using basic Canopy commands, to start the browser and communicate with the 2048 page (tasks 1 to 4),
Expand Down