`%Project 'Untitled'%
`%Version 0.026%
`======================
Type ItemType rem Chris Tate( v0.007,v0.022) - Type in progress...
Name$
Price#
Owner
Image
Object
Description$
Action
BuildUpDelay
MinimumExperienceLevel
Endtype
Type BitMap_Pixel_Type Color As Integer, View As Byte EndType : Global Dim BitMap_Buffer(800,600) As BitMap_Pixel_Type rem VisualProg (v0.017) - this bitmap container, from 2D graphics
goto _jmp_finalFunctionBlock0001 rem VisualProg (v0.009) - form the space for code
function printf(arg_x,arg_y,arg_str$,arg_color) : set cursor arg_x,arg_y : ink arg_color,0 : print arg_str$
endfunction rem VisualProg (v0.015)
function printBitMap(posx,posy,width,height) : for y=0 to height : for x=0 to width : BitMap_Buffer(x,y).View=rnd(255) : printf(posx+x*8,posy+y*8,chr$(BitMap_Buffer(x,y).View),BitMap_Buffer(x,y).Color) : next x : next y
endfunction rem VisualProg (v0.021) out graphic to [x,y]
function hexToInt(arg_hex$) rem VisualProg (v0.023) convert for loading TextBitMap
local result as integer
result=0
for i=1 to len(arg_hex$)
char$=(mid$(arg_hex$,i))
if (char$="1") then inc result,0x01*16^(len(arg_hex$)-i)
if (char$="2") then inc result,0x02*16^(len(arg_hex$)-i)
if (char$="3") then inc result,0x03*16^(len(arg_hex$)-i)
if (char$="4") then inc result,0x04*16^(len(arg_hex$)-i)
if (char$="5") then inc result,0x05*16^(len(arg_hex$)-i)
if (char$="6") then inc result,0x06*16^(len(arg_hex$)-i)
if (char$="7") then inc result,0x07*16^(len(arg_hex$)-i)
if (char$="8") then inc result,0x08*16^(len(arg_hex$)-i)
if (char$="9") then inc result,0x09*16^(len(arg_hex$)-i)
if (char$="A") then inc result,0x0A*16^(len(arg_hex$)-i)
if (char$="B") then inc result,0x0B*16^(len(arg_hex$)-i)
if (char$="C") then inc result,0x0C*16^(len(arg_hex$)-i)
if (char$="D") then inc result,0x0D*16^(len(arg_hex$)-i)
if (char$="E") then inc result,0x0E*16^(len(arg_hex$)-i)
if (char$="F") then inc result,0x0F*16^(len(arg_hex$)-i)
next i
endfunction result
function loadBitMap12BitFromMemory(arg_bin$) rem VisualProg (v0.025) loading TextBitMap12Bit
color=0 : x=-1 : y=0
repeat
if (left$(arg_bin$,1)="\")
inc y : x=-1 : arg_bin$=right$(arg_bin$,len(arg_bin$)-1)
else
if (left$(arg_bin$,1)="~")
inc x : BitMap_Buffer(x,y).Color=oldcolor : arg_bin$=right$(arg_bin$,len(arg_bin$)-1)
else
inc x : tmp$=left$(arg_bin$,3) : color=rgb(hexToInt(mid$(tmp$,1))*0x0F,hexToInt(mid$(tmp$,2))*0x0F,hexToInt(mid$(tmp$,3))*0x0F) : BitMap_Buffer(x,y).Color=color : arg_bin$=right$(arg_bin$,len(arg_bin$)-3) : oldColor=color
endif
endif
until (len(arg_bin$)<3)
endfunction
_jmp_finalFunctionBlock0001: rem VisualProg (v0.006) - start program. Above will be functions
#constant nl chr$(13)+chr$(10) : rem TheComet (v0.005) - Use this to add new lines inside print statements, e.g. "this line"+nl+"is over this line"
Global CharacterName$ = "Mysterious Outlander" rem Chris Tate (v0.001)
Global CharacterPositionX#=0.0, CharacterPositionY#=0.0, CharacterPositionZ#=0.0 rem VisualProg (v0.002)
printa("{w}You, "+CharacterName$+", push open the shabby doors of the town's inn and\nenter. The dry desert dust flows around you dramatically, highlighted by the\nrays of the setting sun. The desolate chatter of drunk emotions ceases to be,\nas all eyes set on you. "+chr$(34)+"{r}What be your name, stranger?{w}"+chr$(34)+"\nthe bartender asks from across the room.{g}"):input "Enter your name ->", CharacterName$ : rem TheComet (v0.003, v0.008, v0.026) Fixed new lines, now uses printa instead of print
_try_again_idiot: rem TheComet (v0.010) For when the player is too stupid to press the given keys
For i = 1 to 4 : Print : Next i : Ink RGB(0,255,0),0 : Print "Greetings " + CharacterName$ + ", what be the purpose of your visit? " : Wait 2000 : Input "Enter reply > [D] 'Give me a drink' [S] 'Tell me a story' [W] 'I need work' [G]'I have something to give to you' "; option$ ` Chris Tate (v0.004,v0.011) Move input down a bit
Select Upper$(option$) rem Chris Tate (v0.013) Bartender reply
Case "D" `-----------------------
Endcase
Case "G" `-----------------------
Endcase
Case "W" `-----------------------
Endcase
Case "S" `-----------------------
Endcase
Case Default
cls:set cursor 0,0:print chr$(34)+"Bahahahaaa!"+chr$(34)+" the bartender bellowed. "+chr$(34)+"Your brain cavity wouldn't"+nl+"make a drinkin' cup for a canary!"+chr$(34):goto _try_again_idiot : rem TheComet(v0.014, v0.020) - Looks like the player is too stupid - added insults
Endcase
Endselect
_option_drink: rem TheComet(v0.012) The character chose a drink!
Cls : For i = 1 to 20 : Wait 20 : beerColour = Rgb(i*10,i*6,i*(5*(i>17))) : Box 0, Screen Height()-((i*1.0)*Screen Height()/25), Screen Width(), Screen Height()-(((i+1)*1.0)*Screen Height()/25), beerColour, beerColour , beerColour, beerColour : Next i : Wait 1000 rem Chris Tate (v0.016,v0.018,v0.019) - Background transition indicating the filling of beer; version 0.016; Had to reinsert because the code was incorrectly altered
Return ` You can now close your labels in the same entry
function printa(s$) :for p=0 to len(s$):c$=right$(left$(s$,p),1):if c$="{":for p2=p+1 to len(s$):c2$=right$(left$(s$,p2),1):if c2$="}":exit:endif:next p2:dec p2,1:c$=right$(left$(s$,p2),p2-p):p=p2+1:if len(c$)>1:ink hexToInt(c$),0:else:if lower$(c$)="r":ink 0xFFFF0000,0:endif:if lower$(c$)="g":ink 0xFF00FF00,0:endif:if lower$(c$)="b":ink 0xFF0000FF,0:endif:if lower$(c$)="y":ink 0xFFFFFF00,0:endif:if lower$(c$)="l":ink 0xFF00FFFF,0:endif:if lower$(c$)="m":ink 0xFFFF00FF,0:endif:if lower$(c$)="w":ink 0xFFFFFFFF,0:endif:endif:c$="":endif:if c$="\":inc p:if right$(left$(s$,p),1)="n":print :endif:c$="":endif:printc c$:next p:print : rem TheComet (v0.024) printa supports colour changes mid-sentence, and doesn't screw up DBPs internal cursor when mixing with newlines. "nl" IS DEPRECATED. Colours are specified between {} brackets, w=white, r=red, g=green, b=blue, y=yellow, m=magenta, l=lightblue. You may also specify a CAPITAL hex value, e.g. {FF00FFFF}. New lines are specified with \n.
endfunction
v0.026 - Enter bar scene now uses
printa for pretty text formatting. This fixes what GG mentioned before about overlapping text.
@Chris
I did a lot of cleaning up and refactoring on the python script to make it more comprehensible, and I wrote docstrings for all of the methods. Here it is:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'TheComet'
import sys
import math
class DBPGameStats(object):
def __init__(self, stream):
# define ranks - feel free to add more!
self.__entries = dict()
self.__rank_names = {
'0': 'Total n00b',
'1': 'You call that Programming?',
'2': 'Colon Apprentice',
'3': 'Programmer with no Life',
'4': 'Fantastic Elastic Spastic',
'5': 'Flowz with da Codez'
}
self.__extract(stream)
def __extract(self, stream):
"""
Internal method for extracting all of the statistical data from a stream
containing the code.
"""
valid_comment_qualifiers = ('rem', '`', '//')
last_unique_version = ""
for line in stream:
# gets the string at the end of a line with all of the version info
comment = ''
for comment_qualifier in valid_comment_qualifiers:
pos = line.rfind(comment_qualifier)
if pos == -1:
continue
comment = line[pos:].strip(' '+comment_qualifier)
break
# confirm comment is valid
if any(comment.find(x) == -1 for x in '()'):
# apparently it wasn't valid! Add the line character count to the last unique version
if not last_unique_version == "":
self.__entries[last_unique_version]['code character count'] += len(line)
continue
# extract the name, version, and optional comment
author = comment[:comment.find('(')].strip()
versions = [x.strip() for x in comment[comment.find('(')+1:comment.find(')')].split(',')]
comment = comment[comment.find(')')+1:].strip()
# add exracted data to internal dictionary
for version in versions:
if not version in self.__entries:
self.__entries[version] = dict()
self.__entries[version]['author'] = author
self.__entries[version]['comment'] = comment
self.__entries[version]['is unique'] = False
self.__entries[version]['code character count'] = 0
# only the first version is unique
last_unique_version = versions[0]
# requested by Chris - Unique entries - Flag the first version appearing in the list
# of versions as unique. This allows the calculation of experience points and levels
self.__entries[last_unique_version]['is unique'] = True
# Unique entries also store how many characters of code existed on that line
self.__entries[last_unique_version]['code character count'] = len(line)
def get_list_of_authors(self):
"""
Generates an alphabetically sorted list of strings of all contributing names.
:return: The list of names.
"""
authors = list()
for key, value in self.__entries.iteritems():
if not value['author'] in authors:
authors.append(value['author'])
return sorted(authors)
def get_list_of_versions(self, author):
"""
:return: Generates a sorted list of all versions the specified author created.
"""
versions = list()
for key, value in self.__entries.iteritems():
if value['author'] == author:
versions.append(key)
return sorted(versions)
def get_list_of_unique_versions(self, author):
"""
Generates a sorted list of all unique versions the specified author created.
Unique versions are different from normal versions in that there is only ever
one unique version per line of code, whereas there can be more than one version
per line of code.
:return: Returns a list of unique versions associated with the specified author.
"""
unique_versions = list()
for key, value in self.__entries.iteritems():
if value['author'] == author and value['is unique']:
unique_versions.append(key)
return sorted(unique_versions)
def get_code_character_count(self, author):
"""
:return: Returns the total character count of the specified author.
"""
count = 0
for key, value in self.__entries.iteritems():
if value['author'] == author and value['is unique']:
count += value['code character count']
return count
def get_author_level(self, author):
"""
Calculates and returns what level the specified author is.
Formula used is: sqrt(unique_versions/1.25)
"""
return int(math.floor(math.sqrt(len(self.get_list_of_unique_versions(author))/1.25)))
def get_author_rank(self, level):
"""
Looks up the rank (if any) for the specified level.
:return: The rank string.
"""
level = str(level)
if level in self.__rank_names:
return self.__rank_names[level]
else:
return "no rank exists for this level"
def print_all_data(self):
"""
Outputs all statistical data available.
"""
print('sorted version list\n=====================')
self.print_sorted_version_list()
print('\ncontribution statistics\n====================================')
self.print_contribution_statistics()
print('\nauthor statistics\n======================')
self.print_author_statistics()
def print_sorted_version_list(self):
"""
Outputs a sorted list of versions with the associated author and optional comments.
"""
for key in sorted(self.__entries):
print('{0}: {1:30}: "{2}"'.format(key, self.__entries[key]['author'], self.__entries[key]['comment']))
def print_contribution_statistics(self):
"""
Prints statistical data related to contribution.
"""
for author in self.get_list_of_authors():
print('{0:30}: contributed {1} versions, {2} unique versions, and a total of {3} characters of code'.format(
author,
len(self.get_list_of_versions(author)),
len(self.get_list_of_unique_versions(author)),
self.get_code_character_count(author)
))
def print_author_statistics(self):
"""
Prints statistical data related to the author himself/herself.
"""
for author in self.get_list_of_authors():
level = self.get_author_level(author)
print('{0:30}: Level {1} - "{2}"'.format(
author,
level,
self.get_author_rank(level)
))
if __name__ == '__main__':
with open('code.txt', 'rb') as f:
stats = DBPGameStats(f)
stats.print_all_data()
sys.exit(0)
It is theoretically python 3.x compliant, but I'm getting a "TypeError: Type str doesn't support the buffer API", which
appears to be a bug in python 3.x itself. Python 3.x is still a little wonky, you are best off using 2.x.