<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.robnugen.com/w/index.php?action=history&amp;feed=atom&amp;title=Programming%3ATcl_Fiction%21_%28unauthorized_copy%29</id>
	<title>Programming:Tcl Fiction! (unauthorized copy) - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.robnugen.com/w/index.php?action=history&amp;feed=atom&amp;title=Programming%3ATcl_Fiction%21_%28unauthorized_copy%29"/>
	<link rel="alternate" type="text/html" href="https://wiki.robnugen.com/w/index.php?title=Programming:Tcl_Fiction!_(unauthorized_copy)&amp;action=history"/>
	<updated>2026-04-07T01:46:46Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://wiki.robnugen.com/w/index.php?title=Programming:Tcl_Fiction!_(unauthorized_copy)&amp;diff=750&amp;oldid=prev</id>
		<title>Rob: Protected &quot;Programming:Tcl Fiction! (unauthorized copy)&quot;: don&#039;t want anyone to muck with this copy; they should work with the original [edit=sysop:move=sysop]</title>
		<link rel="alternate" type="text/html" href="https://wiki.robnugen.com/w/index.php?title=Programming:Tcl_Fiction!_(unauthorized_copy)&amp;diff=750&amp;oldid=prev"/>
		<updated>2008-12-21T09:30:04Z</updated>

		<summary type="html">&lt;p&gt;Protected &amp;quot;&lt;a href=&quot;/wiki/Programming:Tcl_Fiction!_(unauthorized_copy)&quot; title=&quot;Programming:Tcl Fiction! (unauthorized copy)&quot;&gt;Programming:Tcl Fiction! (unauthorized copy)&lt;/a&gt;&amp;quot;: don&amp;#039;t want anyone to muck with this copy; they should work with the original [edit=sysop:move=sysop]&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:30, 21 December 2008&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Rob</name></author>
	</entry>
	<entry>
		<id>https://wiki.robnugen.com/w/index.php?title=Programming:Tcl_Fiction!_(unauthorized_copy)&amp;diff=747&amp;oldid=prev</id>
		<title>Rob: unauthorized copy (with some edits to make it work on MediaWiki</title>
		<link rel="alternate" type="text/html" href="https://wiki.robnugen.com/w/index.php?title=Programming:Tcl_Fiction!_(unauthorized_copy)&amp;diff=747&amp;oldid=prev"/>
		<updated>2008-12-21T09:19:55Z</updated>

		<summary type="html">&lt;p&gt;unauthorized copy (with some edits to make it work on MediaWiki&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt; THIS IS AN UNAUTHORIZED COPY OF THE PAGE Fiction!.  THE ORIGINAL PAGE IS HERE: [http://wiki.tcl.tk/21324 Fiction!]&lt;br /&gt;
&lt;br /&gt;
(I&amp;#039;m making a copy just in case [http://wiki.tcl.tk http://wiki.tcl.tk] goes away, but with a great domain like that, I imagine it will be stable for a while.)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What is Fiction! ?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
It is a new text-based adventure game. It is a small, object-oriented, but full-featured interactive fiction engine.&lt;br /&gt;
&lt;br /&gt;
See also [http://wiki.tcl.tk/863 A text adventure game engine]&lt;br /&gt;
&lt;br /&gt;
It makes use of features of Tcl 8.5, and it has no dependency on Tk, as it is text-only.&lt;br /&gt;
It supports a simple I18N mechanism.&lt;br /&gt;
It requires [http://wiki.tcl.tk/15750 Basique - OO-like namespaces]. Just put the source file named basique.tcl in the directory of Fiction! and it will work.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[http://wiki.tcl.tk/9126 Sarnold] is the creator of this software. It is delivered under a BSD-like license, like Tcl.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;The code&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;tcl&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env tclsh&lt;br /&gt;
&lt;br /&gt;
package require Tcl 8.5&lt;br /&gt;
# the OO layer&lt;br /&gt;
source basique.tcl&lt;br /&gt;
&lt;br /&gt;
# bootstrapping&lt;br /&gt;
set debug yes&lt;br /&gt;
# the standalone demo version&lt;br /&gt;
set demo yes&lt;br /&gt;
&lt;br /&gt;
# I18N&lt;br /&gt;
# Change this to &amp;quot;en&amp;quot; if you want messages in English&lt;br /&gt;
set lang fr&lt;br /&gt;
if $demo {set lang en}&lt;br /&gt;
&lt;br /&gt;
proc assert {expr {msg &amp;quot;assertion failed&amp;quot;}} {if {![uplevel 1 [list expr $expr]]} {error $msg}}&lt;br /&gt;
proc iassert {expr {msg &amp;quot;assertion failed&amp;quot;}} {if {![uplevel 1 [list expr $expr]]} {error [i $msg]}}&lt;br /&gt;
proc ? {bool iftrue iffalse} {&lt;br /&gt;
	if {$bool} {return $iftrue}&lt;br /&gt;
	set iffalse&lt;br /&gt;
}&lt;br /&gt;
proc way? {to} {&lt;br /&gt;
	set to [string tolower $to]&lt;br /&gt;
	set to [string map {south s north n west w east e} $to]&lt;br /&gt;
	iassert [regexp {[senw]|s[ew]|n[ew]|e[ns]|w[ns]} $to] &amp;quot;invalid direction&amp;quot;&lt;br /&gt;
	set to&lt;br /&gt;
}&lt;br /&gt;
# normalizes a namespace&lt;br /&gt;
proc nsnorm val {&lt;br /&gt;
	namespace eval $val namespace current&lt;br /&gt;
}&lt;br /&gt;
proc nseq {a b} {&lt;br /&gt;
	string equal [nsnorm $a] [nsnorm $b]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc i {s} {&lt;br /&gt;
	if {$::lang eq &amp;quot;fr&amp;quot; &amp;amp;&amp;amp; [info exists ::msg($s)]} {&lt;br /&gt;
		return $::msg($s)&lt;br /&gt;
	}&lt;br /&gt;
	set s&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc iputs {s} {warn [i $s]}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ack et fail: shorthands to return true and return false&lt;br /&gt;
interp alias {} ack {} return true&lt;br /&gt;
interp alias {} fail {} return false&lt;br /&gt;
# a useful proc: removes an element from a list,&lt;br /&gt;
# even with multiple elements&lt;br /&gt;
proc lremove {list elt} {&lt;br /&gt;
	while {[set i [lsearch -exact $list $elt]]&amp;gt;=0} {&lt;br /&gt;
		set list [lreplace $list $i $i]&lt;br /&gt;
	}&lt;br /&gt;
	set list&lt;br /&gt;
}&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
basique::class Room {&lt;br /&gt;
	variable name&lt;br /&gt;
	variable ways&lt;br /&gt;
	variable objs &amp;quot;&amp;quot;&lt;br /&gt;
	variable description&lt;br /&gt;
	proc __init__ {desc args} {&lt;br /&gt;
		# do not change set$opt to set $opt&lt;br /&gt;
		# because this is a dispatched command&lt;br /&gt;
		set-name [self]&lt;br /&gt;
		set-description $desc&lt;br /&gt;
		foreach {opt val} $args {[self]::set$opt $val}&lt;br /&gt;
	}&lt;br /&gt;
	proc __destroy__ {} {&lt;br /&gt;
		foreach o [-&amp;gt; objs] {$o destroy}&lt;br /&gt;
	}&lt;br /&gt;
	proc seek {seek} {&lt;br /&gt;
		instance&lt;br /&gt;
		set res &amp;quot;&amp;quot;&lt;br /&gt;
		foreach o $objs {&lt;br /&gt;
			if {[$o match $seek]} {&lt;br /&gt;
				lappend res $o&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		set res&lt;br /&gt;
	}&lt;br /&gt;
	proc watch {} {&lt;br /&gt;
		instance&lt;br /&gt;
		foreach o $objs {$o watch}&lt;br /&gt;
	}&lt;br /&gt;
	proc add {what} {&lt;br /&gt;
		lappend [. objs] $what&lt;br /&gt;
	}&lt;br /&gt;
	proc remove {a} {&lt;br /&gt;
		instance&lt;br /&gt;
		set objs [lremove $objs $a]&lt;br /&gt;
	}&lt;br /&gt;
	proc set-description val {set [. description] $val}&lt;br /&gt;
	proc set-name val {set [. name] $val}&lt;br /&gt;
	proc ways {to name} {&lt;br /&gt;
		set to [way? $to]&lt;br /&gt;
		variable ways&lt;br /&gt;
		dict set ways $to $name&lt;br /&gt;
	}&lt;br /&gt;
	proc where {way} {&lt;br /&gt;
		variable ways&lt;br /&gt;
		dict get $ways [way? $way]&lt;br /&gt;
	}&lt;br /&gt;
	proc object {args} {&lt;br /&gt;
		Object new {*}$args -place [self]&lt;br /&gt;
	}&lt;br /&gt;
	proc person {args} {&lt;br /&gt;
		Person new {*}$args -place [self]&lt;br /&gt;
	}&lt;br /&gt;
	proc here {} {&lt;br /&gt;
		warn [-&amp;gt; description]&lt;br /&gt;
		dict for {dir room} [-&amp;gt; ways] {&lt;br /&gt;
			set dir [join [split $dir &amp;quot;&amp;quot;] -]&lt;br /&gt;
			# set direction in english&lt;br /&gt;
			set dir [string map {n north w west e east s south} $dir]&lt;br /&gt;
			# i18n&lt;br /&gt;
			warn [format [i [format &amp;quot;There is a way to the %s to %%s.&amp;quot; $dir]] [$room -&amp;gt; name]]&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	variable leave StdLeave&lt;br /&gt;
	proc StdLeave {} {&lt;br /&gt;
		warn &amp;quot;[i &amp;quot;You leave&amp;quot;] [-&amp;gt; name].&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	proc Leave {} {eval [-&amp;gt; leave]}&lt;br /&gt;
}&lt;br /&gt;
		&lt;br /&gt;
basique::class Object {&lt;br /&gt;
	variable name&lt;br /&gt;
	variable use &amp;quot;&amp;quot;&lt;br /&gt;
	variable take {ack &amp;quot;you take the object&amp;quot;}&lt;br /&gt;
	variable act fail&lt;br /&gt;
	variable place Home&lt;br /&gt;
	variable desc &amp;quot;No desc&amp;quot;&lt;br /&gt;
	proc __init__ {desc args} {&lt;br /&gt;
		set-name [self]&lt;br /&gt;
		set [. desc] $desc&lt;br /&gt;
		foreach {opt val} $args {[self]::set$opt $val}&lt;br /&gt;
	}&lt;br /&gt;
	proc __destroy__ {} {[-&amp;gt; quality] destroy}&lt;br /&gt;
	proc in val {nseq $val [-&amp;gt; place]}&lt;br /&gt;
	proc set-place val {&lt;br /&gt;
		[-&amp;gt; place] remove [self]&lt;br /&gt;
		set [. place] $val&lt;br /&gt;
		$val add [self]&lt;br /&gt;
	}&lt;br /&gt;
	proc set-name val {set [. name] $val}&lt;br /&gt;
	proc match seek {string match -nocase $seek [-&amp;gt; name]}&lt;br /&gt;
	proc use {onwhat body} {dict set [. use] [nsnorm $onwhat] $body}&lt;br /&gt;
	proc Use {onwhat} {&lt;br /&gt;
		variable use&lt;br /&gt;
		set onwhat [nsnorm $onwhat]&lt;br /&gt;
		if {[dict exists $use $onwhat]} {&lt;br /&gt;
			eval [dict get $use $onwhat]&lt;br /&gt;
		} else {&lt;br /&gt;
			iputs &amp;quot;Nothing happens.&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	proc take {val msg} {set [. take] [handler $val $msg]}&lt;br /&gt;
	proc Take {} {handle [-&amp;gt; take] }&lt;br /&gt;
	proc act {val msg} {set [. act] [handler $val $msg]}&lt;br /&gt;
	proc Act {} {handle [-&amp;gt; act]}&lt;br /&gt;
	proc watch {} {iputs &amp;quot;[-&amp;gt; desc] ([-&amp;gt; name])&amp;quot;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# some small procs to handle message and body of a handler&lt;br /&gt;
proc handler {val msg} {&lt;br /&gt;
	list $val $msg&lt;br /&gt;
}&lt;br /&gt;
proc handle {n} {&lt;br /&gt;
	iputs [lindex $n 1]&lt;br /&gt;
	uplevel 1 [lindex $n 0]&lt;br /&gt;
}&lt;br /&gt;
basique::class Person {&lt;br /&gt;
	variable name&lt;br /&gt;
	variable inventory &amp;quot;&amp;quot;&lt;br /&gt;
	variable talk {default dummy}&lt;br /&gt;
	variable place Home&lt;br /&gt;
	variable state default&lt;br /&gt;
	variable description&lt;br /&gt;
	proc __init__ {args} {&lt;br /&gt;
		set-name [self]&lt;br /&gt;
		foreach {opt val} $args {[self]::set$opt $val}&lt;br /&gt;
	}&lt;br /&gt;
	proc set-state val {set [. state] $val}&lt;br /&gt;
	proc set-place val {&lt;br /&gt;
		[-&amp;gt; place] remove [self]&lt;br /&gt;
		set [. place] $val&lt;br /&gt;
		$val add [self]&lt;br /&gt;
	}&lt;br /&gt;
	proc watch {} {&lt;br /&gt;
		iputs [-&amp;gt; description]&lt;br /&gt;
	}&lt;br /&gt;
	proc gives {person obj} {&lt;br /&gt;
		$obj set-place $person&lt;br /&gt;
	}&lt;br /&gt;
	proc set-description val {set [. description] $val}&lt;br /&gt;
	proc The {} {string trim &amp;quot;[phrase The] [-&amp;gt; name]&amp;quot;}&lt;br /&gt;
	proc set-name val {&lt;br /&gt;
	    set [. name] $val&lt;br /&gt;
	    set-description [format [i &amp;quot;Here is %s.&amp;quot;] [-&amp;gt; name]]&lt;br /&gt;
	}&lt;br /&gt;
	proc match seek {string match $seek [-&amp;gt; name]}&lt;br /&gt;
	proc set-talk val {talk $val}&lt;br /&gt;
	proc talk args {&lt;br /&gt;
		assert {[llength $args]&amp;gt;0}&lt;br /&gt;
		set val [lindex $args end]&lt;br /&gt;
		set state [getopts [lrange $args 0 end-1] -state default]&lt;br /&gt;
		dict set [. talk] $state $val&lt;br /&gt;
	}&lt;br /&gt;
	proc says {txt} {warn &amp;quot;[-&amp;gt; name]: $txt&amp;quot;}&lt;br /&gt;
	&lt;br /&gt;
	proc object {args} {&lt;br /&gt;
		lappend [. inventory] [Object new {*}$args]&lt;br /&gt;
	}&lt;br /&gt;
	proc Talk {args} {eval [dict get [-&amp;gt; talk] [-&amp;gt; state]]}&lt;br /&gt;
	proc dummy {} {&lt;br /&gt;
		warn [random [i &amp;quot;Talk less and act much!&amp;quot;] [i &amp;quot;Nothing happens.&amp;quot;]]&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
basique::class Ego {&lt;br /&gt;
	variable inventory &amp;quot;&amp;quot;&lt;br /&gt;
	variable place&lt;br /&gt;
	variable history &amp;quot;&amp;quot;&lt;br /&gt;
	variable score 0&lt;br /&gt;
	proc __init__ {where} {puts {Fiction! (c) Stephane Arnold 2008&lt;br /&gt;
BSD-like Tcl license (see http://www.tcl.tk/)}&lt;br /&gt;
		set [. place] $where&lt;br /&gt;
	}&lt;br /&gt;
	proc __destroy__ {} {&lt;br /&gt;
		foreach o [-&amp;gt; inventory] {$o destroy}&lt;br /&gt;
		[-&amp;gt; place] destroy&lt;br /&gt;
	}&lt;br /&gt;
	proc register {args} {&lt;br /&gt;
		switch -- [lindex $args 0] {&lt;br /&gt;
			Save {}&lt;br /&gt;
			default {lappend [. history] $args}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	proc score {n} {incr [. score] $n}&lt;br /&gt;
	proc WinTheGame {} {&lt;br /&gt;
		iputs Congratulations!&lt;br /&gt;
		PutScore&lt;br /&gt;
	}&lt;br /&gt;
	proc LoseTheGame {} {&lt;br /&gt;
		iputs Sorry...&lt;br /&gt;
		PutScore&lt;br /&gt;
	}&lt;br /&gt;
	proc Save {args} {&lt;br /&gt;
		warn [format [i &amp;quot;This will save the current game to &amp;#039;%s&amp;#039;&amp;quot;] $args]&lt;br /&gt;
		puts -nonewline [i &amp;quot;Are you sure ? (y/n) &amp;quot;]&lt;br /&gt;
		flush stdout&lt;br /&gt;
		gets stdin line&lt;br /&gt;
		if {![string equal $line [i y]]} {&lt;br /&gt;
			iputs &amp;quot;Save aborted.&amp;quot;&lt;br /&gt;
			return&lt;br /&gt;
		}&lt;br /&gt;
		if {[catch {&lt;br /&gt;
			set fd [open $args w]&lt;br /&gt;
			# we write the history to a file&lt;br /&gt;
			foreach l [-&amp;gt; history] {puts $fd $l}&lt;br /&gt;
			close $fd&lt;br /&gt;
		} msg]} {&lt;br /&gt;
			error [format [i &amp;quot;Cannot write to &amp;#039;%s&amp;#039;: %s&amp;quot;] $args $msg]&lt;br /&gt;
		}&lt;br /&gt;
		iputs &amp;quot;Game saved&amp;quot;&lt;br /&gt;
	}			&lt;br /&gt;
	proc say {txt} {warn &amp;quot;[i I]: $txt&amp;quot;}&lt;br /&gt;
	proc match {match} {&lt;br /&gt;
		set res &amp;quot;&amp;quot;&lt;br /&gt;
		foreach o [-&amp;gt; inventory] {&lt;br /&gt;
			if {[$o match *$match*]} {lappend res $o}&lt;br /&gt;
		}&lt;br /&gt;
		concat $res [[-&amp;gt; place] seek *$match*]&lt;br /&gt;
	}&lt;br /&gt;
	proc seekN {n list} {&lt;br /&gt;
		if {$n == 1} {return [seek $list]}&lt;br /&gt;
		set i [llength $list]&lt;br /&gt;
		incr i -1&lt;br /&gt;
		while {[llength [match [lrange $list 0 $i]]]!=1} {&lt;br /&gt;
			incr i -1&lt;br /&gt;
			if {$i &amp;lt; 0} {error &amp;quot;[i &amp;quot;cannot find object or person&amp;quot;]: $list&amp;quot;}&lt;br /&gt;
		}&lt;br /&gt;
		concat [match [lrange $list 0 $i]] [seekN [incr n -1] [lrange $list [expr {$i+1}] end]]&lt;br /&gt;
	}&lt;br /&gt;
	proc seek {list} {&lt;br /&gt;
		# seek for an object or a person matching a list of strings&lt;br /&gt;
		set match [match $list]&lt;br /&gt;
		if {[llength $match] == 0} {&lt;br /&gt;
			error &amp;quot;[i &amp;quot;cannot find object or person&amp;quot;]: $list&amp;quot;			&lt;br /&gt;
		}&lt;br /&gt;
		if {[llength $match]&amp;gt;1} {return [probe $match]}&lt;br /&gt;
		return [lindex $match 0]&lt;br /&gt;
	}&lt;br /&gt;
	proc probe list {&lt;br /&gt;
		iputs &amp;quot;Did you mean?&amp;quot;&lt;br /&gt;
		fori i x $list {warn &amp;quot;[expr {$i+1}]: [$x -&amp;gt; name]&amp;quot;}&lt;br /&gt;
		while yes {&lt;br /&gt;
			warn -nonewline &amp;quot;1-[llength $list]? &amp;quot;&lt;br /&gt;
			flush stdout&lt;br /&gt;
			gets stdin answer&lt;br /&gt;
			if {![string is integer $answer]} { &lt;br /&gt;
				iputs &amp;quot;must be an integer&amp;quot;&lt;br /&gt;
				continue&lt;br /&gt;
			}&lt;br /&gt;
			if {$answer &amp;gt;0 &amp;amp;&amp;amp; $answer &amp;lt;= [llength $list]} {&lt;br /&gt;
				return [lindex $list [expr {$answer -1}]]&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		# dead end&lt;br /&gt;
	}&lt;br /&gt;
	proc Take {args} {&lt;br /&gt;
		grab [seek $args]&lt;br /&gt;
	}&lt;br /&gt;
	proc Drop {args} {&lt;br /&gt;
		drop [seek $args]&lt;br /&gt;
	}&lt;br /&gt;
	proc PutScore {} {warn [format [i &amp;quot;Your score: %d points.&amp;quot;] [-&amp;gt; score]]}&lt;br /&gt;
	proc Inv {} {&lt;br /&gt;
		PutScore&lt;br /&gt;
		if {[llength [-&amp;gt; inventory]]==0} {&lt;br /&gt;
			iputs &amp;quot;Nothing in your pockets.&amp;quot;&lt;br /&gt;
			return&lt;br /&gt;
		}&lt;br /&gt;
		iputs &amp;quot;In your pockets:&amp;quot;&lt;br /&gt;
		foreach i [-&amp;gt; inventory] {puts &amp;quot;- [$i -&amp;gt; name]&amp;quot;}&lt;br /&gt;
	}&lt;br /&gt;
	proc Look {} {&lt;br /&gt;
		[-&amp;gt; place] here&lt;br /&gt;
		[-&amp;gt; place] watch&lt;br /&gt;
	}&lt;br /&gt;
	proc Help {} {&lt;br /&gt;
		puts [set ::Help_$::lang]&lt;br /&gt;
	}&lt;br /&gt;
	proc Exit {} {&lt;br /&gt;
	    puts -nonewline [i &amp;quot;Are you sure you want to quit ? (y/n) &amp;quot;]&lt;br /&gt;
	    flush stdout&lt;br /&gt;
	    gets stdin c&lt;br /&gt;
	    if {[string equal $c [i y]]} exit&lt;br /&gt;
	}&lt;br /&gt;
	proc Go {way} {&lt;br /&gt;
		variable place&lt;br /&gt;
		if {[catch {set where [$place where $way]}]} {&lt;br /&gt;
			error [i &amp;quot;There is no way like this&amp;quot;]&lt;br /&gt;
		}&lt;br /&gt;
		$place Leave&lt;br /&gt;
		$where here&lt;br /&gt;
		set place $where&lt;br /&gt;
	}&lt;br /&gt;
	proc grab {what} {&lt;br /&gt;
		iassert {![$what in [self]]} &amp;quot;I already have it.&amp;quot;&lt;br /&gt;
		assert {[$what in [-&amp;gt; place]]} &amp;quot;[i &amp;quot;cannot take&amp;quot;] [$what -&amp;gt; name].&amp;quot;&lt;br /&gt;
		assert [$what Take] &amp;quot;[i &amp;quot;cannot take&amp;quot;] [$what -&amp;gt; name].&amp;quot;&lt;br /&gt;
		$what set-place I&lt;br /&gt;
	}&lt;br /&gt;
	proc add val {&lt;br /&gt;
		lappend [. inventory] [nsnorm $val]&lt;br /&gt;
	}&lt;br /&gt;
	proc drop {what} {&lt;br /&gt;
		puts &amp;quot;[i &amp;quot;You drop&amp;quot;] [$what -&amp;gt; name]&amp;quot;&lt;br /&gt;
		$what set-place [-&amp;gt; place]&lt;br /&gt;
	}&lt;br /&gt;
	# to talk with people&lt;br /&gt;
	proc Talk {args} {&lt;br /&gt;
	    [seek $args] Talk&lt;br /&gt;
	}&lt;br /&gt;
	proc remove {what} {&lt;br /&gt;
		instance&lt;br /&gt;
		assert {[lsearch -exact $inventory $what]&amp;gt;=0} &amp;quot;[i &amp;quot;no such object&amp;quot;]: $what&amp;quot;&lt;br /&gt;
		set inventory [lremove $inventory $what]&lt;br /&gt;
	}&lt;br /&gt;
	proc Use {args} {&lt;br /&gt;
		eval use [seekN 2 $args]&lt;br /&gt;
	}&lt;br /&gt;
	proc use {what onwhat} {&lt;br /&gt;
		assert {[$what in [self]]} &amp;quot;[i &amp;quot;I do not have&amp;quot;] [$what -&amp;gt; name].&amp;quot;&lt;br /&gt;
		$what Use $onwhat&lt;br /&gt;
	}&lt;br /&gt;
	proc act {what} {&lt;br /&gt;
		assert {[$what in [self]] || [$what in [-&amp;gt; place]]} &amp;quot;[i &amp;quot;cannot use&amp;quot;] [$what -&amp;gt; name].&amp;quot;&lt;br /&gt;
		$what Act&lt;br /&gt;
	}&lt;br /&gt;
	proc Act {args} {act [seek $args]}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# returns a random element within arguments&lt;br /&gt;
proc random {args} {&lt;br /&gt;
	lindex $args [expr {int(rand()*[llength $args])}]&lt;br /&gt;
}&lt;br /&gt;
# manage options&lt;br /&gt;
proc getopts {alist opt default} {&lt;br /&gt;
	if {[llength $alist] == 0} {&lt;br /&gt;
		return $default&lt;br /&gt;
	}&lt;br /&gt;
	assert {[llength $alist]%2 == 0}&lt;br /&gt;
	foreach {key val} $alist {&lt;br /&gt;
		if {$key eq $opt} {return $val}&lt;br /&gt;
	}&lt;br /&gt;
	return $default&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc fori {x var lst body} {&lt;br /&gt;
	uplevel 1 set $x 0&lt;br /&gt;
	uplevel 1 [list foreach $var $lst &amp;quot;$body\nincr $x&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
interp alias {} warn {} puts&lt;br /&gt;
proc Direction {s} {&lt;br /&gt;
	set s [Direction_$::lang $s]&lt;br /&gt;
	iassert [regexp {^([nsew]|n[we]|s[ew]|w[ns]|e[ns])$} $s] &amp;quot;invalid direction&amp;quot;&lt;br /&gt;
	list Go $s&lt;br /&gt;
}&lt;br /&gt;
proc Direction_en {s} {&lt;br /&gt;
	string map {- &amp;quot;&amp;quot; north n east e west w south s} $s&lt;br /&gt;
}&lt;br /&gt;
proc Direction_fr s {&lt;br /&gt;
	string map {est e o w} [string map {- &amp;quot;&amp;quot; nord n ouest o sud s} $s]&lt;br /&gt;
}&lt;br /&gt;
proc cmd {word} {&lt;br /&gt;
	if {![catch {&lt;br /&gt;
		set dir [Direction $word]&lt;br /&gt;
	}]} {&lt;br /&gt;
		return $dir&lt;br /&gt;
	}&lt;br /&gt;
	set commands [dict create fr {&lt;br /&gt;
		quitter Exit&lt;br /&gt;
		exit Exit&lt;br /&gt;
		laisser Drop&lt;br /&gt;
		prendre Take&lt;br /&gt;
		parler Talk&lt;br /&gt;
		utiliser Use&lt;br /&gt;
		actionner Act&lt;br /&gt;
		regarder Look&lt;br /&gt;
		va Go&lt;br /&gt;
		aller Go&lt;br /&gt;
		inventaire Inv&lt;br /&gt;
		aider Help&lt;br /&gt;
		sauver Save&lt;br /&gt;
	} en {&lt;br /&gt;
		quit Exit&lt;br /&gt;
		exit Exit&lt;br /&gt;
		drop Drop&lt;br /&gt;
		take Take&lt;br /&gt;
		talk Talk&lt;br /&gt;
		use Use&lt;br /&gt;
		act Act&lt;br /&gt;
		look Look&lt;br /&gt;
		go Go&lt;br /&gt;
		inventory Inv&lt;br /&gt;
		help Help&lt;br /&gt;
		save Save&lt;br /&gt;
	}]&lt;br /&gt;
	set res &amp;quot;&amp;quot;&lt;br /&gt;
	foreach {name cmd} [dict get $commands $::lang] {&lt;br /&gt;
		if {[string match $word* $name]} {&lt;br /&gt;
			lappend res $cmd&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	if {[llength $res]==1} {return [lindex $res 0]}&lt;br /&gt;
	error &amp;quot;I do not understand&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
proc dummy {word} {&lt;br /&gt;
	expr {[lsearch [set ::dummy_$::lang] $word]&amp;gt;=0}&lt;br /&gt;
}&lt;br /&gt;
set dummy_en {a the on with}&lt;br /&gt;
set dummy_fr {à un une la le les des sur avec}&lt;br /&gt;
# set printing to stdout on/off&lt;br /&gt;
proc Warn {bool} {&lt;br /&gt;
	if {$bool} {&lt;br /&gt;
		proc warn {s} {puts $s; after 300}&lt;br /&gt;
	} else {&lt;br /&gt;
		proc warn {s} {}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
set Help_en {Commands are:&lt;br /&gt;
quit/exit	Exit the game&lt;br /&gt;
n-s-w-e		Go to the north, south...&lt;br /&gt;
take obj	Take an object&lt;br /&gt;
drop obj	Drop an object&lt;br /&gt;
look		Take a look upon your environment&lt;br /&gt;
act obj		Activate an object&lt;br /&gt;
talk person	Talk to a person&lt;br /&gt;
use obj what	Use an object on something/someone&lt;br /&gt;
go n-s-w-e	Go to the north, south...}&lt;br /&gt;
&lt;br /&gt;
set Help_fr {Voici les ordres que je comprends :&lt;br /&gt;
quitter/exit		Termine le jeu&lt;br /&gt;
n-s-o-e			Se déplacer au nord, sud,....&lt;br /&gt;
prendre obj		Prendre un objet&lt;br /&gt;
laisser obj		Lacher un objet&lt;br /&gt;
regarder		Regarder autour de soi&lt;br /&gt;
actionner obj		Actionner un objet&lt;br /&gt;
parler personne		Parler à quelqu&amp;#039;un&lt;br /&gt;
utiliser obj chose	Utiliser un objet sur qq chose ou qq&amp;#039;un&lt;br /&gt;
go n-s-o-e		Se déplacer}&lt;br /&gt;
proc main {{file &amp;quot;&amp;quot;}} {&lt;br /&gt;
	if {$file ne &amp;quot;&amp;quot;} {&lt;br /&gt;
		puts [format [i &amp;quot;Restoring data from %s...&amp;quot;] $file]&lt;br /&gt;
		Warn off&lt;br /&gt;
		if {[catch {&lt;br /&gt;
			set i 0&lt;br /&gt;
			set fd [open $file]&lt;br /&gt;
			while {![eof $fd]} {&lt;br /&gt;
				gets $fd line&lt;br /&gt;
				if {$line ne &amp;quot;&amp;quot;} {&lt;br /&gt;
					catch {eval I $line}&lt;br /&gt;
					eval I register $line&lt;br /&gt;
				}&lt;br /&gt;
				# display a progress indicator&lt;br /&gt;
				incr i&lt;br /&gt;
				if {$i % 100 == 0} {puts -nonewline .}&lt;br /&gt;
			}&lt;br /&gt;
			close $fd&lt;br /&gt;
		} msg info]} {&lt;br /&gt;
			puts $msg&lt;br /&gt;
			puts stderr $info&lt;br /&gt;
			exit&lt;br /&gt;
		}&lt;br /&gt;
		Warn on&lt;br /&gt;
	}&lt;br /&gt;
	I Look&lt;br /&gt;
	while 1 {&lt;br /&gt;
		puts -nonewline &amp;quot;&amp;gt; &amp;quot;&lt;br /&gt;
		flush stdout&lt;br /&gt;
		gets stdin line&lt;br /&gt;
		if {[catch {cmd [lindex $line 0]} cmd]} {&lt;br /&gt;
			iputs &amp;quot;I do not understand, please type help&amp;quot;&lt;br /&gt;
			continue&lt;br /&gt;
		}&lt;br /&gt;
		# filters dummy words (to, a, the, ...)&lt;br /&gt;
		# in any language&lt;br /&gt;
		set res [list]&lt;br /&gt;
		foreach i [lrange $line 1 end] {&lt;br /&gt;
			if {![dummy $i]} {lappend res $i}&lt;br /&gt;
		}&lt;br /&gt;
		if {[catch {eval I $cmd $res} msg info]} {&lt;br /&gt;
			puts $msg&lt;br /&gt;
			if {$::debug} {puts $info}&lt;br /&gt;
		} else {&lt;br /&gt;
			eval I register $cmd $res&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# I18N en Francais&lt;br /&gt;
array set msg {&lt;br /&gt;
	&amp;quot;assertion failed&amp;quot; &amp;quot;échec de contrôle de données&amp;quot;&lt;br /&gt;
	&amp;quot;Restoring data from %s...&amp;quot; &amp;quot;Restauration de la partie stockée dans %s...&amp;quot;&lt;br /&gt;
	&amp;quot;Talk less and act much!&amp;quot; &amp;quot;Moins de paroles, plus d&amp;#039;action !&amp;quot;&lt;br /&gt;
	&amp;quot;too many words&amp;quot; &amp;quot;trop de mots dans la commande&amp;quot;&lt;br /&gt;
	&amp;quot;You leave&amp;quot; &amp;quot;Vous quittez&amp;quot;&lt;br /&gt;
	&amp;quot;He is&amp;quot; &amp;quot;C&amp;#039;est un&amp;quot;&lt;br /&gt;
	&amp;quot;Here is&amp;quot; &amp;quot;Il y a&amp;quot;&lt;br /&gt;
	&amp;quot;This will save the current game to &amp;#039;%s&amp;#039;&amp;quot; &amp;quot;Cela enregistrera dans &amp;#039;%s&amp;#039; la partie en cours.&amp;quot;&lt;br /&gt;
	&amp;quot;Game saved&amp;quot; &amp;quot;Jeu sauvegardé&amp;quot;&lt;br /&gt;
	&amp;quot;Are you sure ? (y/n) &amp;quot; &amp;quot;Êtes-vous sûr ? (o/n) &amp;quot;&lt;br /&gt;
	&amp;quot;You take&amp;quot; &amp;quot;Vous prenez&amp;quot;&lt;br /&gt;
	&amp;quot;Nothing happens.&amp;quot; &amp;quot;Rien ne se passe.&amp;quot;&lt;br /&gt;
	&amp;quot;There is a way to the north to %s.&amp;quot; &amp;quot;Il y a une voie au nord vers %s.&amp;quot;&lt;br /&gt;
	&amp;quot;There is a way to the south to %s.&amp;quot; &amp;quot;Il y a une voie au sud vers %s.&amp;quot;&lt;br /&gt;
	&amp;quot;There is a way to the west to %s.&amp;quot; &amp;quot;Il y a une voie à l&amp;#039;ouest vers %s.&amp;quot;&lt;br /&gt;
	&amp;quot;There is a way to the east to %s.&amp;quot; &amp;quot;Il y a une voie à l&amp;#039;est vers %s.&amp;quot;&lt;br /&gt;
	north nord south sud west ouest east est &lt;br /&gt;
	&amp;quot;There is no way like this&amp;quot; &amp;quot;Il n&amp;#039;y a pas de voie dans cette direction.&amp;quot;&lt;br /&gt;
	&amp;quot;You drop&amp;quot; &amp;quot;Vous déposez&amp;quot; I Moi&lt;br /&gt;
	&amp;quot;There is&amp;quot; &amp;quot;Il y a&amp;quot;&lt;br /&gt;
	&amp;quot;use %s on what?&amp;quot; &amp;quot;Sur quoi voulez-vous utiliser %s ?&amp;quot;&lt;br /&gt;
	&amp;quot;Your score: %d points.&amp;quot; &amp;quot;Votre score est de %d points.&amp;quot;&lt;br /&gt;
	&amp;quot;In your pockets:&amp;quot; &amp;quot;Dans tes poches :&amp;quot;&lt;br /&gt;
	&amp;quot;Nothing in your pockets.&amp;quot; &amp;quot;Tu n&amp;#039;as rien dans les poches.&amp;quot;&lt;br /&gt;
	&amp;quot;I do not understand, please type help&amp;quot; &amp;quot;Je ne comprends pas. (tape aide)&amp;quot;&lt;br /&gt;
	&amp;quot;Are you sure you want to quit ? (y/n) &amp;quot; &amp;quot;Etes-vous sûr de vouloir quitter ce programme ? (o/n) &amp;quot;&lt;br /&gt;
	y o&lt;br /&gt;
	&amp;quot;Cannot write to &amp;#039;%s&amp;#039;: %s&amp;quot; &amp;quot;Impossible d&amp;#039;accéder à &amp;#039;%s&amp;#039; : %s&amp;quot;&lt;br /&gt;
	&amp;quot;cannot find object or person&amp;quot; &amp;quot;je ne trouve pas cet objet ou cette personne&amp;quot;&lt;br /&gt;
	&amp;quot;Here is %s.&amp;quot; &amp;quot;Il y a %s.&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
## &lt;br /&gt;
 #  Testing material&lt;br /&gt;
 ##&lt;br /&gt;
if $demo {&lt;br /&gt;
    Room new Home {Home, sweet home...} -name {your home} &lt;br /&gt;
    Home ways n Garden&lt;br /&gt;
    Room new Garden {You stand in a wonderful garden with flowers of all essences.} -name &amp;quot;the garden&amp;quot;&lt;br /&gt;
    Home object Rasoir {There is a razor that is really dirty.} -name &amp;quot;a razor&amp;quot;&lt;br /&gt;
    Garden ways s Home&lt;br /&gt;
    Rasoir take ack {You take the razor.}&lt;br /&gt;
    Rasoir act ack {You are shaving. Mmmh, this is nice.}&lt;br /&gt;
    Garden object Flower {A beautiful rose.} -name &amp;quot;a flower&amp;quot;&lt;br /&gt;
    Flower take ack {You take this rose.}&lt;br /&gt;
    Garden person Claire -name &amp;quot;a girl&amp;quot; -state unknown&lt;br /&gt;
    Claire talk -state unknown {&lt;br /&gt;
	I say &amp;quot;Hi! How do you do?&amp;quot;&lt;br /&gt;
	Claire says &amp;quot;I&amp;#039;m Claire. How do you do?&amp;quot;&lt;br /&gt;
	I say &amp;quot;I&amp;#039;m Julien. Nice to meet you!&amp;quot;&lt;br /&gt;
	Claire says &amp;quot;Nice to meet you, Julien!&amp;quot;&lt;br /&gt;
	Claire set-name Claire&lt;br /&gt;
	Claire set-state default&lt;br /&gt;
    }	&lt;br /&gt;
    Claire talk -state default dummy&lt;br /&gt;
    Flower use Claire {&lt;br /&gt;
	Claire says &amp;quot;Oh, thanks a lot! I love these flowers.&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
} else {source aventure.txt}&lt;br /&gt;
## End of material  ##&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ego new I Home&lt;br /&gt;
eval main $argv&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rob</name></author>
	</entry>
</feed>