<commit_before>module Pong where

import Prelude
import CSS (green)
import Control.Monad.Eff (Eff)
import Data.Maybe (Maybe(..))
import Graphics.Canvas (clearRect, getContext2D, getCanvasElementById, CANVAS)
import Graphics.Drawing (fillColor, Drawing, render, rectangle, filled, black)

type BatState = {pos :: Number, dir :: Move}

type BallState = { x :: Number, y :: Number, dir :: BallDir }

data DirX = Left | Right
data DirY = Up | Down
data BallDir = BallDir DirX DirY

newtype PongState = PongState { p1 :: BatState
                              , p2 :: BatState
                              , ball :: BallState}

data Player = One | Two
data Move = Direction DirY | Stop
data PongCommand = MovePlayer {player :: Player, move :: Move} | Step

initial :: PongState
initial = PongState {p1: {pos:0.0, dir: Stop}, p2: {pos:0.0, dir: Stop}, ball: {x: 10.0, y: 10.0, dir: BallDir Right Down}}

sendCommand :: PongCommand -> PongState -> PongState
sendCommand (MovePlayer {player, move}) (PongState s) = PongState (
   case player of
     One -> s {p1 = s.p1 {dir = move}}
     Two -> s {p2 = s.p2 {dir = move}})

sendCommand Step (PongState s) = PongState (
  s { p1 = updateBat s.p1
    , p2 = updateBat s.p2
    , ball = updateBall s})


updateBall :: forall g .     
  { ball :: BallState
  , p1 :: BatState
  , p2 :: BatState
  | g                 
  }
  -> BallState
updateBall {p1, p2, ball:ball@{x, y, dir:(BallDir dx dy)}} = 
  let nx = newX in
  let ny = newY in
  ball { x = nx.p
       , y = ny.p
       , dir = BallDir nx.d ny.d}
  where
    s = 5.0
    f :: forall d . (d -> d) -> Number -> Number -> (Number -> Boolean) -> d -> {p :: Number, d :: d}
    f flip o n c d = 
         if (c n)
         then {p: o, d: flip d}
         else {p: n, d: d}
    fX = f flipX x
    fY = f flipY y
    newX = case dx of<commit_msg>Reset score<commit_after>module Pong where

import Prelude
import CSS (green)
import Control.Category ((<<<))
import Control.Monad.Eff (Eff)
import Data.Maybe (Maybe(..))
import Graphics.Canvas (clearRect, getContext2D, getCanvasElementById, CANVAS)
import Graphics.Drawing (fillColor, Drawing, render, rectangle, filled, black)

type BatState = {pos :: Number, dir :: Move}

type BallState = { x :: Number, y :: Number, dir :: BallDir }

data DirX = Left | Right
data DirY = Up | Down
data BallDir = BallDir DirX DirY

newtype PongState = PongState { p1 :: BatState
                              , p2 :: BatState
                              , ball :: BallState
                              , score :: {one :: Int, two :: Int}}

data Player = One | Two
data Move = Direction DirY | Stop
data PongCommand = MovePlayer {player :: Player, move :: Move} | Step

newRound :: forall t10.                    
  t10
  -> { p1 :: BatState
     , p2 :: BatState                 
     , ball :: BallState               
     , score :: t10       
     }                         
newRound score = { p1: {pos:0.0, dir: Stop}
                 , p2: {pos:0.0, dir: Stop}
                 , ball: {x: 10.0, y: 10.0, dir: BallDir Right Down}
                 , score: score}

initial :: PongState
initial = PongState  (newRound {one: 0, two: 0})

sendCommand :: PongCommand -> PongState -> PongState
sendCommand (MovePlayer {player, move}) (PongState s) = PongState (
   case player of
     One -> s {p1 = s.p1 {dir = move}}
     Two -> s {p2 = s.p2 {dir = move}})

sendCommand Step (PongState s) = PongState (
  updateScore (s { p1 = updateBat s.p1
    , p2 = updateBat s.p2
    , ball = updateBall s}))


updateScore :: { ball :: { x :: Number      
          , y :: Number      
          , dir :: BallDir   
          }                  
, score :: { one :: Int      
           , two :: Int      
           }                 
, p1 :: { pos :: Number      
        , dir :: Move        
        }                    
, p2 :: { pos :: Number      
        , dir :: Move        
        }                    
}                            
-> { p1 :: { pos :: Number   
           , dir :: Move     
           }                 
   , p2 :: { pos :: Number   
           , dir :: Move     
           }                 
   , ball :: { x :: Number   
             , y :: Number   
             , dir :: BallDir
             }               
   , score :: { one :: Int   
              , two :: Int   
              }              
   }                         
updateScore s
  | s.ball.x + ballSize.w > canvasSize.w = newRound { one: s.score.one + 1
                                                    , two: s.score.two}
  | s.ball.x < 0.0 = newRound {one: s.score.one
                            , two: s.score.two + 1}
  | otherwise = s
    
updateBall :: forall g .     
  { ball :: BallState
  , p1 :: BatState
  , p2 :: BatState
  | g                 
  }
  -> BallState
updateBall {p1, p2, ball:ball@{x, y, dir:(BallDir dx dy)}} = 
  let nx = newX in
  let ny = newY in
  ball { x = nx.p
       , y = ny.p
       , dir = BallDir nx.d ny.d}
  where
    s = 5.0
    f :: forall d . (d -> d) -> Number -> Number -> (Number -> Boolean) -> d -> {p :: Number, d :: d}
    f flip o n c d = 
         if (c n)
         then {p: o, d: flip d}
         else {p: n, d: d}
    fX = f flipX x
    fY = f flipY y
    newX = case dx of
{'fraction_non_alphanumeric': 0.12716542927850752, 'fraction_numerical': 0.014467923091566724, 'mean_word_length': 1.5283926852743022, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7368424', 'n_tokens_mistral': 1756, 'n_tokens_neox': 1701, 'n_words': 551}