about summary refs log tree commit diff stats
path: root/src/pokedex/pokedex.rkt
blob: 586f341daba3237f924c951a2dadee471162d105 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#lang racket

(require net/url
         net/url-connect
         json
         slideshow/pict
         racket/draw)

;; let's try to make a pokedex in racket!

;; first step will be to write a function to query the pokeAPI
;; like so, https://pokeapi.co/api/v2/pokemon/ditto

;; once there is a function in place that returns data I will
;; have a choice to make -- do I want to always query the API,
;; do I want to cache results, or do I want to create an offline
;; repository of poke-data to search through and sometimes update?

;; API URL
(define *POKE-API* "https://pokeapi.co/api/v2/")

(define (get-pokemon id)
    "queries the api, returns a butt ton of info"
	(call/input-url (string->url (~a *POKE-API* "pokemon/" id)) ; ~a, like string-append but appends *either* strings or numbers to a string
                get-pure-port
                (compose string->jsexpr port->string))) ; QUESTION: could I use read-json here, instead?

(define (dex-entry id)
    "selects the info we need from the api, builds a hash table of the data that will build the entry"
    (let ([poke-data (get-pokemon id)])
        (define entry-data (make-hash))
        (hash-set! entry-data "name"   (hash-ref poke-data 'name))
        (hash-set! entry-data "id"     (hash-ref poke-data 'id))
        (hash-set! entry-data "sprite" (hash-ref (hash-ref poke-data 'sprites) 'front_default))
        (hash-set! entry-data "stats"  (hash-ref poke-data 'stats))
        (hash-set! entry-data "types"  (hash-ref poke-data 'types))
        entry-data))

(define (inspector h)
  "display the contents of a hash table for human eyeballs and let the hash table fall back out"
  (hash-map h
            (lambda (k v)
              (if (list? v) (map ; consider making this if a cond and testing for lists/hash tables to recursively dive into nested data
                             (lambda (x) (inspector x)) v)
                  (display (~a "  key: " k "\nvalue: " v "\n=====\n")))))
  h)

; (inspector (dex-entry 11))
; (inspector (dex-entry "bulbasaur"))

(define (capitalize-first-letter str)
  "utility to capitalize the first letter of a string"
  (cond
    [(non-empty-string? str)
     (define first-letter-str
       (substring str 0 1))
     (define rest-str
       (substring str 1 (string-length str)))
     (string-append (string-upcase first-letter-str)
                    rest-str)]
    [else ""]))

(define (get-image id sprite-file-name)
  "download a sprite"
  (define img (hash-ref (dex-entry id) "sprite"))
  (define img-url
    (string->url img))
  (define the-data
    (parameterize ([current-https-protocol 'secure])
      (port->bytes (get-pure-port img-url))))
  (define out (open-output-file sprite-file-name))
  (write-bytes the-data out)
  (close-output-port out)
  (display-image sprite-file-name))

(define (display-image image)
  "display a sprite"
  (define display-image (bitmap (make-object bitmap% image)))
  (frame (scale display-image 1)))

(define (see-pokemon id)
  "check to see if we've already got a sprite, if we don't, get it"
  (define sprite-file-name
    (~a "imgs/" id ".png"))
  (if (file-exists? sprite-file-name)
      (display-image sprite-file-name)
      (get-image id sprite-file-name)))

;; FIXME: I'd very much like to sort out how to display stats, types, and maybe the evolution chain.
(define (poke id [debug #f])
  "display some basic info about a pokemon given it's name or id"
  (define poke-data (dex-entry id))
  (when debug
      (inspector poke-data))
  (displayln (~a "name: "
                 (capitalize-first-letter (hash-ref poke-data "name"))))
  (displayln (~a "id:   " (hash-ref poke-data "id")))
  (see-pokemon (hash-ref poke-data "name"))) ; using name here prevents duplicate files with different names, id.png v name.png

(poke "zapdos")
(poke 74)
(poke "charizard")
(poke "slowking")
(poke "slowbro")
(poke "slowpoke")
(poke "kingler")