This is my first attempt at a trade solver/AI. The solver gets a list of possible trades it can make, such as "Buy a Starship for 250 Credits" and "Make 300 Credits by selling 1 Starship" and the solver will use this to try to achieve some defined goal.
Here's the code snippet. In this snippet the example has many possible trades, and the solver is told to get a battlecruiser by linking together trades that eventually reach that goal. If you copy&paste the code, execute, and press the spacebar, it will give you the list of trades that must be done in order to get the battlecruiser.
rem I made this with space trade and exploration simulations in mind, but it could work with any sort of trading.
sync on
sync rate 0
cls
set display mode 1024,768,32
type trade_type
amount
exist
name as string
endtype
dim trade(100) as trade_type
type quantity_type
name as string
amount as integer
endtype
dim trade_have(100,20) as quantity_type
dim trade_give(100,20) as quantity_type
dim trade_receive(100,20) as quantity_type
dim currently_have(20) as quantity_type
add_have("Credits",100)
rem possible trades:
newtrade=add_trade("Make 110 Credits by selling 1 Gem")
add_trade_give(newtrade,"Gem",1)
add_trade_receive(newtrade,"Credits",110)
newtrade=add_trade("Buy a Starship for 250 Credits.")
add_trade_give(newtrade,"Credits",250)
add_trade_receive(newtrade,"Starship",1)
newtrade=add_trade("Buy a Hyperdrive for 150 Credits.")
add_trade_give(newtrade,"Credits",150)
add_trade_receive(newtrade,"Hyperdrive",1)
newtrade=add_trade("Buy a Hyperdrive for 50 Credits.")
add_trade_give(newtrade,"Credits",50)
add_trade_receive(newtrade,"Hyperdrive",1)
newtrade=add_trade("Make 100 Credits by selling 1 Hyperdrive.")
add_trade_give(newtrade,"Hyperdrive",1)
add_trade_receive(newtrade,"Credits",100)
newtrade=add_trade("Buy a Engine for 50 credits")
add_trade_give(newtrade,"Credits",50)
add_trade_receive(newtrade,"Engine",1)
newtrade=add_trade("Buy a Gem for 20 credits")
add_trade_give(newtrade,"Credits",20)
add_trade_receive(newtrade,"Gem",1)
newtrade=add_trade("Buy a Coil for 50 credits")
add_trade_give(newtrade,"Credits",50)
add_trade_receive(newtrade,"Coil",1)
newtrade=add_trade("Buy a Starship for 50 Credits.")
add_trade_give(newtrade,"Credits",50)
add_trade_receive(newtrade,"Starship",1)
newtrade=add_trade("Get a Battlecruiser by giving 2 Starships")
add_trade_give(newtrade,"Starship",2)
add_trade_receive(newtrade,"Battlecruiser",1)
newtrade=add_trade("Buy a Gem for 10 credits")
add_trade_give(newtrade,"Credits",10)
add_trade_receive(newtrade,"Gem",1)
newtrade=add_trade("Make 60 Credits by selling 1 Engine")
add_trade_give(newtrade,"Engine",1)
add_trade_receive(newtrade,"Credits",60)
newtrade=add_trade("Make 100 Credits by selling 1 Engine")
add_trade_give(newtrade,"Engine",1)
add_trade_receive(newtrade,"Credits",100)
global solution_found=0
global solution$=""
dim temp_have(12,20) as quantity_type
dim temp_trade_have(12,20) as quantity_type
dim temp_trade_give(12,20) as quantity_type
dim temp_trade_receive(12,20) as quantity_type
do
cls
print screen fps()
display_current()
display_possible_trades()
print "Goal: Get a Battlecruiser"
print "Press spacekey to solve"
if spacekey()=1
get("Battlecruiser",1)
if solution$=""
print "No Solution!"
else
print "Solution:"
for n=1 to len(solution$) step 2
st$=mid$(solution$,n)+mid$(solution$,n+1)
t=val(st$)
print "Trade ",trade(t).name
next n
endif
print
print
sync
wait key
endif
sync
loop
function get(name$,amount)
solution_found=0
solution$=""
chain_trade(name$,amount,12)
endfunction
function chain_trade(name$,amount,count)
if count<0 then exitfunction 0
if solution_found=0
for c=1 to 20
if currently_have(c).name=name$
if currently_have(c).amount>=amount
solution_found=1
exitfunction 1
endif
endif
next c
endif
for t=1 to 100
if trade(t).exist=1
if meet_requirements_for_trade(t)=1
for c=1 to 20
temp_have(count,c).name=currently_have(c).name
temp_have(count,c).amount=currently_have(c).amount
temp_trade_have(count,c).name=trade_have(t,c).name
temp_trade_have(count,c).amount=trade_have(t,c).amount
temp_trade_give(count,c).name=trade_give(t,c).name
temp_trade_give(count,c).amount=trade_give(t,c).amount
temp_trade_receive(count,c).name=trade_receive(t,c).name
temp_trade_receive(count,c).amount=trade_receive(t,c).amount
next c
for c=1 to 20
if trade_give(t,c).name<>""
for c2=1 to 20
if currently_have(c2).name<>""
if currently_have(c2).name=trade_give(t,c).name
currently_have(c2).amount=currently_have(c2).amount-trade_give(t,c).amount
endif
endif
next c2
endif
if trade_receive(t,c).name<>""
added=0
for c2=1 to 20
if currently_have(c2).name=trade_receive(t,c).name
currently_have(c2).amount=currently_have(c2).amount+trade_receive(t,c).amount
added=1
endif
next c2
if added=0
for c2=1 to 20
if currently_have(c2).name=""
currently_have(c2).name=trade_receive(t,c).name
currently_have(c2).amount=currently_have(c2).amount+trade_receive(t,c).amount
added=1
exit
endif
next c2
endif
endif
next c
trade(t).amount=trade(t).amount-1
if trade(t).amount=0 then trade(t).exist=0
num$=str$(t)
if len(num$)<2
num$="0"+num$
endif
solution$=solution$+num$
chain_trade(name$,amount,count-1)
trade(t).amount=trade(t).amount+1
trade(t).exist=1
for c=1 to 20
currently_have(c).name=temp_have(count,c).name
currently_have(c).amount=temp_have(count,c).amount
trade_have(t,c).name=temp_trade_have(count,c).name
trade_have(t,c).amount=temp_trade_have(count,c).amount
trade_give(t,c).name=temp_trade_give(count,c).name
trade_give(t,c).amount=temp_trade_give(count,c).amount
trade_receive(t,c).name=temp_trade_receive(count,c).name
trade_receive(t,c).amount=temp_trade_receive(count,c).amount
next c
if solution_found=1
exitfunction 1
else
solution$=left$(solution$,len(solution$)-2)
endif
endif
endif
next t
endfunction 0
function meet_requirements_for_trade(t)
for i=1 to 20
if trade_have(t,i).name<>""
met=0
for c=1 to 20
if currently_have(c).name=trade_have(t,i).name
if currently_have(c).amount<trade_have(t,i).amount
exitfunction 0
else
met=1
endif
endif
next c
if met=0
exitfunction 0
endif
endif
next i
for i=1 to 20
if trade_give(t,i).name<>""
met=0
for c=1 to 20
if currently_have(c).name=trade_give(t,i).name
if currently_have(c).amount<trade_give(t,i).amount
exitfunction 0
else
met=1
endif
endif
next c
if met=0
exitfunction 0
endif
endif
next i
endfunction 1
function display_possible_trades()
print "Possible Trades"
for t=1 to 100
if trade(t).exist=1
print trade(t).name
` print " Have:";
for i=1 to 20
if trade_have(t,i).name<>""
print " ",trade_have(t,i).amount," ",trade_have(t,i).name,"(s)";
endif
next i
` print
print " Give:";
for i=1 to 20
if trade_give(t,i).name<>""
print " ",trade_give(t,i).amount," ",trade_give(t,i).name,"(s)";
endif
next i
print
print " Receive:";
for i=1 to 20
if trade_receive(t,i).name<>""
print " ",trade_receive(t,i).amount," ",trade_receive(t,i).name,"(s)";
endif
next i
print
endif
next t
endfunction
function display_current()
print "Current possesions:"
for i=1 to 20
if currently_have(i).name<>""
print currently_have(i).amount," ",currently_have(i).name,"(s)"
endif
next i
endfunction
function add_have(name$,amount)
for i=1 to 20
if currently_have(i).name=name$
currently_have(i).amount=trade_have(i).amount+amount
exitfunction 1
endif
if currently_have(i).name=""
currently_have(i).name=name$
currently_have(i).amount=amount
exitfunction 1
endif
next i
endfunction 0
function add_trade(name$)
for n=1 to 100
if trade(n).exist=0
trade(n).exist=1
trade(n).name=name$
trade(n).amount=1
for i=1 to 20
trade_have(n,i).name=""
trade_have(n,i).amount=0
trade_give(n,i).name=""
trade_give(n,i).amount=0
trade_receive(n,i).name=""
trade_receive(n,i).amount=0
next i
exitfunction n
endif
next n
endfunction -1
function add_trade_have(t,name$,amount)
for i=1 to 20
if trade_have(t,i).name=name$
trade_have(t,i).amount=trade_have(t,i).amount+amount
exitfunction 1
endif
if trade_have(t,i).name=""
trade_have(t,i).name=name$
trade_have(t,i).amount=amount
exitfunction 1
endif
next i
endfunction 0
function add_trade_give(t,name$,amount)
for i=1 to 20
if trade_give(t,i).name=name$
trade_give(t,i).amount=trade_give(t,i).amount+amount
exitfunction 1
endif
if trade_give(t,i).name=""
trade_give(t,i).name=name$
trade_give(t,i).amount=amount
exitfunction 1
endif
next i
endfunction 0
function add_trade_receive(t,name$,amount)
for i=1 to 20
if trade_receive(t,i).name=name$
trade_receive(t,i).amount=trade_receive(t,i).amount+amount
exitfunction 1
endif
if trade_receive(t,i).name=""
trade_receive(t,i).name=name$
trade_receive(t,i).amount=amount
exitfunction 1
endif
next i
endfunction 0
It would be interesting to expand this to work with other things, like locations and distances, such as "buying" 1 lightyear of travel for 10 quarts of hyperdrive fuel, and adding movement costs that way, thereby discouraging the solver from making lots of trades from opposite ends of the galaxy.
Edit:
This solver could also be adapted to work with a goal directed reasoning system. Like if for example the overall goal given to the system was to "get to the 20th floor of building xyz", the solver could be given a pool of possible subgoals, such as: "find elevator by looking around in building", "look around in building by being in building", "find building by using map", "go to floor x by going to elevator", "go to elevator by finding elevator", and the solver would find a way to string the subgoals together in an order that worked and acheived the overall goal.