public int CountOfEntries(GameMemory zorkFile) { ByteAddress startOfDictionary = ptrToDictionary(zorkFile); int countSepCharacters = CountOfSeparatorCharacters(zorkFile); WordAddress ptrToEntryCount = new WordAddress(startOfDictionary.Value + 1 + countSepCharacters + 2); return zorkFile.ReadWord(ptrToEntryCount).Value; }
public Word[] GetContentsOfNthEntry(int n, GameMemory zorkFile) { int entrySize = GetEntrySizeInBytes(n, zorkFile); // I have been assuming that the above call will return 4, since that // is how many bytes are in a word entry. But it think this size // allows there to be arbitrary entries after all the words, and they might // be of up to this size. // Two questions: // 1. How do I know that we are in the size-regulated, has words-in-order // part of the dictionary? // 2. How do I know the size of the entries that are after the words, // in the arbitrary-sized part of the table? int entrySizeInWords = entrySize / 2; Word[] retval = new Word[entrySizeInWords]; WordAddress ptrStartOfEntry = GetOffSetOfNthEntry(n, zorkFile); for(int i = 0; i < entrySizeInWords; i++) { WordAddress here = new WordAddress(ptrStartOfEntry.Value + (i * 2)); retval[i] = zorkFile.ReadWord(here); } return retval; }
public Word ReadWord(WordAddress address) { ByteAddress highByteAddress = Bits.AddressOfHighByte(address); ByteAddress lowByteAddress = Bits.AddressOfLowByte(address); byte high = ReadByte(highByteAddress); byte low = ReadByte(lowByteAddress); return new Word((256 * high) + low); }
public static WordAddress AddressOfAbbreviationByNumber(AbbreviationNumber number, GameMemory memory) { AbbreviationTableBase basePtr = new AbbreviationTableBase(memory); WordAddress addressOfPtrToAbbrTable = new WordAddress(24); WordAddress ptrToAbbrevTable = new WordAddress(memory.ReadWord(addressOfPtrToAbbrTable).Value); WordAddress ptrToChosenAbbrv = ptrToAbbrevTable + (number.Value); WordAddress decompressedAbbrvPtr = new WordAddress(memory.ReadWord(ptrToChosenAbbrv).Value * 2); return decompressedAbbrvPtr; }
static void Main(string[] args) { string pathToMiniZork = @"..\..\..\minizork.z3"; GameMemory minizork = GameMemory.OpenFile(pathToMiniZork); //ReadDictionaryTillBreak(minizork); DictionaryHelper dictionary = new DictionaryHelper(); Console.WriteLine($"Dictionary is expected to have {dictionary.CountOfEntries(minizork)} entries"); string expectedFirst10EntriesString = "$ve . , #comm #rand #reco #unre \" a about"; string[] expectedFirst10Entries = expectedFirst10EntriesString.Split(' '); List<string> nEntries = new List<string>(); int n = 10; for(int i = 0; i < n; i++ ) { string entry = dictionary.ReadNthEntry(i, minizork).Print; Console.WriteLine($"Expected: {expectedFirst10Entries[i]} but Found: {entry}"); } WordAddress testText = new WordAddress(0xb106); IEnumerable<Zchar> story = Zchar.ReadWordsTillBreak(testText, minizork); char[] toPrint = Zchar.DecodeFromZString(story, minizork).ToArray(); string printMe = new string(toPrint); Console.Write(printMe); TestMemoryBase(); TestReadingAndWritingGameState(); TestReadVersionNumberFromFile(pathToMiniZork); //TestBitTwiddling(); //19 t 0d h 0a e 00 _ 05 ? 05 ? //1e y 14 o 1a u 17 r 00 _ 05 ? ReadFromAbbrTable(pathToMiniZork); Console.WriteLine("Now reading every abbreviation in order"); for(int i = 0; i < 96; i++) { AbbreviationNumber num = new AbbreviationNumber(i); var zchars = Zchar.ReadAbbrevTillBreak(num, minizork); var normalChars = Zchar.DecodeFromZString(zchars, minizork, false) .ToArray(); Console.WriteLine($"Abbrev number {i} : {new string(normalChars)}"); } Console.ReadKey(); }
public static List<Zchar> ReadStringFromAddress(WordAddress address, GameMemory memory) { throw new System.NotImplementedException(); List<Zchar> retval = new List<Zchar>(); Word word = memory.ReadWord(address); while(!word.IsTerminal()) { //Zchar char1 = new Zchar(new AbbreviationNumber(Bits.FetchBits(BitNumber.Bit14, BitSize.Size5, word))); //Zchar char2 = new Zchar(new AbbreviationNumber(Bits.FetchBits(BitNumber.Bit9, BitSize.Size5, word))); //Zchar char3 = new Zchar(new AbbreviationNumber(Bits.FetchBits(BitNumber.Bit4, BitSize.Size5, word))); //retval.Add(char1); //retval.Add(char2); //retval.Add(char3); address = address + 1; word = memory.ReadWord(address); } return retval; }
public DictionaryEntry(string print, WordAddress offset, int ix) { this.Print = print; this.OffsetIntoFile = offset; this.IndexIntoDictionary = ix; }
public void WriteWord(WordAddress wordAddress, Word toWrite) { short bytes = toWrite.Value; byte high = (byte)((bytes >> 8) & 0xFF); byte low = (byte)(bytes & 0xFF); this.WriteByte(Bits.AddressOfHighByte(wordAddress), high); this.WriteByte(Bits.AddressOfLowByte(wordAddress), low); }
public AbbreviationTableBase(GameMemory memory) { WordAddress addrOfTableBasePtr = new WordAddress(24); WordAddress addressOfTableBase = new WordAddress(memory.ReadWord(addrOfTableBasePtr).Value); this.value = addressOfTableBase.Value; }
public static IEnumerable<char> YieldAbbreviationFromAbbreviationNumber(AbbreviationNumber number, GameMemory memory) { WordAddress addressOfPtrToAbbrTable = new WordAddress(24); WordAddress ptrToAbbrevTable = new WordAddress(memory.ReadWord(addressOfPtrToAbbrTable).Value); WordAddress address = AbbreviationTableBase.AddressOfAbbreviationByNumber(number, memory); Word word = memory.ReadWord(address); while (true) { char[] firstThree = Zchar.PrintWordAsZchars(word).ToCharArray(); foreach (char ch in firstThree) { yield return ch; } if (word.IsTerminal()) { yield break; } address = address + 1; word = memory.ReadWord(address); } }
public static ByteAddress AddressOfLowByte(WordAddress address) { return new ByteAddress(address.Value + 1); }
public static IEnumerable<Zchar> ReadAbbrevTillBreak(AbbreviationNumber num, GameMemory memory) { WordAddress addressOfPtrToAbbrTable = new WordAddress(24); WordAddress ptrToAbbrevTable = new WordAddress(memory.ReadWord(addressOfPtrToAbbrTable).Value); WordAddress ptrChosenAbbrev = AbbreviationTableBase.AddressOfAbbreviationByNumber(num, memory); return ReadWordsTillBreak(ptrChosenAbbrev, memory); }
private static void ReadDictionaryTillBreak(GameMemory zorkFile) { DictionaryHelper dictionary = new DictionaryHelper(); WordAddress startOfEntries = dictionary.GetOffSetOfNthEntry(0, zorkFile); WordAddress ptrFirstEntry = new WordAddress(startOfEntries.Value); var test = Zchar.ReadWordsTillBreak(ptrFirstEntry, zorkFile); char[] result = Zchar.DecodeFromZString(test, zorkFile, permitRecurse: false) .ToArray(); Console.Write(new string(result)); }
private static void TestReadingAndWritingGameState() { string storyState = "Listen to a story 'bout a guy named Al"; string interpreterState = "Who lived in the sewer with his hamster pal"; int expectedImmutableSize = Encoding.UTF8.GetByteCount(storyState); byte[] immutablePart = Encoding.UTF8.GetBytes(storyState); int expectedDynamicSize = Encoding.UTF8.GetByteCount(interpreterState); byte[] dynamicPart = Encoding.UTF8.GetBytes(interpreterState); ImmutableByteWrapper changingPart = new ImmutableByteWrapper(dynamicPart); GameMemory gameState = new GameMemory(immutablePart, changingPart); WordAddress zeroPointer = new WordAddress(0); List<WordAddress> firstFivePointers = Enumerable.Range(0, 5) .Select(el => zeroPointer + el) .ToList(); IEnumerable<ByteAddress> firstTenByteAddress = Enumerable.Range(0, 10) .Select(el => new ByteAddress(el)); byte[] firstTenBytes = firstTenByteAddress .Select(p => gameState.ReadByte(p)) .ToArray(); byte[] firstFiveWords = firstFivePointers .Select(p => gameState.ReadWord(p)) .SelectMany(word => new byte[] { (byte)(word.Value & 0xFF), (byte)((word.Value >> 8) & 0xFF) }) .ToArray(); string firstFive = new string(Encoding.UTF8.GetChars(firstFiveWords)); byte[] firstFiveTransposed = firstFivePointers .Select(p => gameState.ReadWord(p)) .SelectMany(word => new byte[] { (byte)((word.Value >> 8) & 0xFF), (byte)(word.Value & 0xFF) }) .ToArray(); string firstFiveTransposedRead = new string(Encoding.UTF8.GetChars(firstFiveTransposed)); string whatIRead = new String(Encoding.UTF8.GetChars(firstTenBytes)); //test writing to game state: //replace "Who lived " with // "zzCheese2 " byte[] toWrite = Encoding.UTF8.GetBytes("zzCheese2 "); System.Diagnostics.Debug.Assert(toWrite.Length == firstTenBytes.Length); Enumerable.Range(0, 10) .Select(el => new { address = new ByteAddress(el), val = toWrite[el] }) .ToList() .ForEach(item => gameState.WriteByte(item.address, item.val)); byte[] firstTenBytesAgain = firstTenByteAddress .Select(p => gameState.ReadByte(p)) .ToArray(); string mutated = new string(Encoding.UTF8.GetChars(firstTenBytesAgain)); //test writing Words instead of bytes to game state: byte[] toWriteWordWise = Encoding.UTF8.GetBytes("aaZZeess33"); WordAddress zero = new WordAddress(0); for(int i = 0; i < toWriteWordWise.Length - 1; i += 2) { int val = (toWriteWordWise[i] * 256 + toWriteWordWise[i + 1]); WordAddress address = zero + i / 2; gameState.WriteWord(address, new Word(val)); } byte[] firstTenBytesAgain2 = firstTenByteAddress .Select(p => gameState.ReadByte(p)) .ToArray(); string mutated2 = new string(Encoding.UTF8.GetChars(firstTenBytesAgain2)); Console.WriteLine($"{whatIRead} became {mutated} and then {mutated2}"); }
private static void ReadFromAbbrTable(string pathToMiniZork) { GameMemory minizork = GameMemory.OpenFile(pathToMiniZork); WordAddress addressOfPtrToAbbrTable = new WordAddress(24); WordAddress ptrToAbbrevTable = new WordAddress(minizork.ReadWord(addressOfPtrToAbbrTable).Value); WordAddress decompressedAddressOfFirstAbbreviation = new WordAddress(minizork.ReadWord(ptrToAbbrevTable).Value * 2); Word word = minizork.ReadWord(decompressedAddressOfFirstAbbreviation); int abbreviationLenght = 0; while (!word.IsTerminal()) { abbreviationLenght++; Console.Write(Zchar.PrintWordAsZchars(word)); word = minizork.ReadWord(decompressedAddressOfFirstAbbreviation + abbreviationLenght); } WordAddress secondAbbrev = AbbreviationTableBase.AddressOfAbbreviationByNumber(new AbbreviationNumber(1), minizork); List<Zchar> wholeSecondAbbrev = Zchar.ReadAbbrevTillBreak(new AbbreviationNumber(2), minizork).ToList(); Console.WriteLine(); word = minizork.ReadWord(secondAbbrev); int len = 0; string accumulator = ""; accumulator += Zchar.PrintWordAsZchars(word); while (true) { len++; word = minizork.ReadWord(secondAbbrev + len); accumulator += Zchar.PrintWordAsZchars(word); if (word.IsTerminal()) break; } Console.WriteLine(accumulator); }
public static IEnumerable<Zchar> ReadWordsTillBreak(WordAddress address, GameMemory memory, ISet<char> breakers = null) { while (true) { Word word = memory.ReadWord(address); Zchar low = new Zchar(Bits.FetchBits(BitNumber.Bit14, BitSize.Size5, word)); Zchar mid = new Zchar(Bits.FetchBits(BitNumber.Bit9, BitSize.Size5, word)); Zchar high = new Zchar(Bits.FetchBits(BitNumber.Bit4, BitSize.Size5, word)); yield return low; yield return mid; yield return high; if (word.IsTerminal(breakers)) { yield break; } address = address + 1; } }
public static ByteAddress AddressOfHighByte(WordAddress address) { return new ByteAddress(address.Value); }