#lang racket
(require 2htdp/universe 2htdp/image "engine.rkt" "robot.rkt" "config.rkt")
(provide world sprite
sprite-left sprite-right sprite-up sprite-down search-sprite
sprite-x sprite-y sprite-dx sprite-dy sprite-energy distance
go-left go-right go-up go-down drop-bomb
bomb? fire? player? robot? blocked? brick? rock?
player robot
run move-robot-default)
(define (tick w)
(letrec ([score-player (world-score-player w)]
[score-robot (world-score-robot w)]
[destruction
(lambda (d)
(if (empty? (search-sprite (sprite-x (first d))
(sprite-y (first d))
fire?
(world-decor w)))
(cons (first d) (tic-tac (rest d))) (cond [(and (player? (first d))
(energy0? (first d))) (begin (set! score-robot (+ score-robot 1))
(cons (new-player (rest d)) (rest d)))]
[(and (robot? (first d))
(energy0? (first d))) (begin (set! score-player (+ score-player 1))
(cons (new-robot (rest d)) (rest d)))]
[else (tic-tac (rest d))])))]
[tic-tac
(lambda (d)
(if (empty? (rest d))
d
(cond [(bomb? (first d)) (cons (tic-tac-bomb (first d) d w) (tic-tac (rest d)))]
[(fire? (first d)) (if (energy0? (first d))
(tic-tac (rest d))
(if (or (> (abs (sprite-dx (first d))) 0)
(> (abs (sprite-dy (first d))) 0))
(append (spread-fire (consume (first d)) (world-decor w))
(tic-tac (rest d)))
(cons (consume (first d)) (tic-tac (rest d)))))]
[(brick? (first d)) (destruction d)]
[(player? (first d)) (destruction (cons (tic-tac-player-or-robot (first d) d IMAGE-PLAYER ENERGY-PLAYER) (rest d)))]
[(robot? (first d)) (destruction (cons (tic-tac-player-or-robot (first d) d IMAGE-ROBOT ENERGY-ROBOT) (rest d)))]
[else (cons (first d) (tic-tac (rest d)))])))]
[move-robot (world-move-robot w)]
[move-player (world-move-player w)]
[d (tic-tac (world-decor w))])
(struct-copy world w
[decor (move-player player (move-robot robot d))]
[score-player score-player] [score-robot score-robot])))
(define (render w)
(letrec ([place-sprites (lambda (sprites image)
(if (empty? sprites)
image
(place-image (if (fire? (first sprites))
(image-fire (first sprites)
(world-decor w))
(sprite-image (first sprites)))
(sprite-x (first sprites))
(sprite-y (first sprites))
(place-sprites (rest sprites) image))))]
[fond-score (overlay (rectangle (* DELTA 3) (- DELTA 8) 'outline 'black)
(rectangle (* DELTA 3) (- DELTA 8) 'solid 'silver))]
[image-score (place-image (text (number->string (world-score-robot w)) 15 'red)
(- WIDTH (* DELTA 2)) (/ DELTA 2)
(place-image (text (number->string (world-score-player w)) 15 'blue)
(* DELTA 2) (/ DELTA 2)
(place-image fond-score (* DELTA 2) (/ DELTA 2)
(place-image fond-score
(- WIDTH (* DELTA 2)) (/ DELTA 2)
(place-image (text "dynablaster" 15 'silver) (* DELTA 10) (/ DELTA 2)
(rectangle WIDTH DELTA 'solid 'dimgray))))))])
(above image-score
(place-sprites (world-decor w) IMAGE-BACKGROUND))))
(define (keypress w s)
(let* ([d (world-decor w)]
[j (player d)])
(if (empty? j)
w
(cond
[(string=? s "up") (struct-copy world w [decor (go-up j d)])]
[(string=? s "down") (struct-copy world w [decor (go-down j d)])]
[(string=? s "left") (struct-copy world w [decor (go-left j d)])]
[(string=? s "right") (struct-copy world w [decor (go-right j d)])]
[(string=? s " ") (struct-copy world w [decor (drop-bomb j d)])]
[else w]))))
(define (initial-world move-robot move-player sound)
(let ([d (make-decor (make-decor BORDER
50
IMAGE-ROCK #f 'rock 0)
100
IMAGE-BRICK #f 'brick 0)])
(world (cons (new-robot d)
(cons (new-player d) d))
move-robot move-player
0 0 sound)))
(define (run [move-robot move-robot-default] [move-player (lambda (r d) d)]
#:sound [with-sound #f])
(big-bang (initial-world move-robot move-player with-sound)
(on-tick tick 0.1)
(to-draw render)
(on-key keypress)))