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 console.html and text-game.scm example file #77

Merged
merged 1 commit into from
Oct 28, 2024
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
87 changes: 87 additions & 0 deletions src/examples/text-game.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
;; This example showcases how to create a simple text-based game in Scheme using Ribbit.
;; Notably, it adds the ability to clear the screen in the console using the `clear` primitive.
;;
;; You can either compile this examples to JavaScript or Python.
;;
;; [JavaScript]
;; $ ./rsc.exe -t js -l r4rs/tc -f+ js/web -o game.js examples/text-game.scm
;; $ cat host/js/console.html | sed "s/INPUT_JAVASCRIPT_FILE_HERE.js/game.js/" > game.html
;; $ open game.html
;;
;; [Python]
;; $ ./rsc.exe -t py -l r4rs/tc -o game.py examples/text-game.scm
;; $ python3 game.py


;; Define the clear primitive for JavaScript and Python hosts
(cond-expand
((host js)

;; In JavaScript, we clear the screen by removing the content of the textarea
;; used as a console.
(define-primitive (clear)
"() => {
document.getElementById('repl').value=''; // Clear the repl
return push(0); // Primitives always push something to the stack
}, // Always need a comma after a primitive
"))

((host py)

;; In python, we clear the screen by calling the 'clear' program using the os.system function.
(define-feature
clear
((import "import os")))

(define-primitive (clear)
"prim(0, lambda: os.system('clear')),")))


;; Utility function to ask questions to the user
(define (ask-question question)
(display question)
(newline)
(read-line))

;; Utility function to ask a question with multiple choices
(define (choice-question question choices)
(display question)
(display " [")
(let loop ((choices choices))
(display (car choices))
(if (null? (cdr choices))
(display "] ")
(begin
(display ", ")
(loop (cdr choices)))))
(newline)
(let ((answer (read-line)))
(if (member answer choices)
answer
(begin
(display "(Invalid answer) ")
(choice-question question choices)))))


;; Game logic
(define (main)

(clear)

(display
"Welcome, you are a detective investigating the death of Watson. He was murdered in his apartment at night.")

(let ((choice
(choice-question
"What do you want to investigate first?"
'("apartment" "local bar" "workplace"))))

(let ((response (ask-question (string-append "What do you want to search first at " choice " ?"))))
(display "You choose search about '")
(display response)
(display "' with some success")
(newline)
(ask-question "The game is finished. Press ENTER to restart the game.")
(main))))

(main)
41 changes: 41 additions & 0 deletions src/host/js/console.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<html>
<head>

<!-- The whole repl is contained in this file -->
<script src="./INPUT_JAVASCRIPT_FILE_HERE.js"></script>

<!-- Highlight.js -->
<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- Styles for REPL -->
<style>
* {
font-family: 'Menlo', monospace;
}
h1, h2, h3{
text-align: center;
width: 100%;
}
div{
font-size: 14px;
}
#repl {
width: 100%;
height: 50vh;
padding: 10px;
background-color: #f8f8f8;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
</style>

</head>
<body>
<h1>Test a scheme program inside the box below!</h1>

<!-- The repl script will replace the div below with a textarea -->
<div id="repl"></div>

</body>
</html>
Loading