Oxygene for Java version of Crossword
Pascal version by Adam Renak: L6 Age ~16
Introduction
See above a description of the Pascal file and the link for the download of the dictionary text file. In the conversion to Oxygene for Java, note the following points.
- Arrays are zero based.
- Individual characters in strings are accessed like an array of char, but in Oxygene are zero based.
- Oxygene, like Pascal, uses nil instead of Java's null.
- Variables are objects and have useful methods such as toString for an Integer and trim (to strip spaces from a string).
- Read becomes System.in.read. We read an array of SByte first, convert this to a string, then trim the trailing spaces.
- Reading lines from a file is achieved using 3 objects: a FileInputStream, an InputStreamReader and a LineNumberReader.
- Procedures and functions become methods (although the original terminology is accepted).
We typed at the Command Prompt cd c:\Oxygene to change the current directory to our project folder. We compiled the program with the command msbuild crossword.oxygene and executed the contents of the resultant jar file with the command java -jar bin\Release\crossword.jar You can open the project file in Visual Studio and execute the program with a click on the green triangle.
The program in crossword.pas
namespace Crossword; { Copyright (c) 2010 Adam Renak Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License, as described at http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/ Converted to Oxygene for Java by PPS (2013) } interface uses java.io.*; var Words, NarrowWords : Array[0 .. 100000] of string; word_length : Integer; Narrowfactor : Integer := -1; const ListLength = 80368; implementation method LoadWordlist; var fis : FileInputStream; isr : InputStreamReader; lnr : LineNumberReader; Count : Integer := -1; begin fis := new FileInputStream('DictWordlist.txt'); isr := new InputStreamReader(fis); lnr := new LineNumberReader(isr); repeat inc(Count); Words[Count] := lnr.readLine; until Words[Count] = nil; fis.close; end; //Narrows the wordlist down to words of similar length method NarrowLength; var Count1, Count2 : Integer; begin Count2 := -1; for Count1 := 0 to ListLength - 1 do begin if word_length = length(words[Count1]) then begin inc(Count2); Narrowwords[Count2] := words[Count1]; Narrowfactor := Count2; //Now Narrowfactor is zero based end; end; end; //Narrows list according to character position. method Narrow(vWord : string; position : integer); var NarrowPos, InsertCount : Integer; begin InsertCount := -1; //Sets the pointer that the new narrowlist begins at. for NarrowPos := 0 to Narrowfactor do //From 0 to last narrowed word if (vWord[position] = narrowwords[NarrowPos][position]) then begin Inc(InsertCount); NarrowWords[InsertCount] := Narrowwords[NarrowPos]; end; Narrowfactor := InsertCount; //Reduces the Narrowfactor end; var CharPosn, writecount : Integer; input_word : array[0 .. 20] of SByte; input_string, lower_case_string, lower_case_word : string; begin Loadwordlist; repeat writeln('Input the word to solve. Use ? to show unknowns:'); input_word := [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32]; System.in.read(input_word); input_string := new string(input_word); lower_case_string := input_string.toLowerCase; lower_case_word := lower_case_string.trim; //Removes trailing spaces word_length := length(lower_case_word); Narrowlength; for CharPosn := 0 to word_length - 1 do //Zero based chars in string if lower_case_word[CharPosn] <> '?' then Narrow(lower_case_word, CharPosn); //Write a list of matching words: writeln('--------------------------------------'); for WriteCount := 0 to Narrowfactor do //Writes possible words writeln('MATCH: ' + NarrowWords[WriteCount].toString); //If no match is found, it writes the five closest matches. if Narrowfactor = -1 then begin writeln('No match found. Try these suggestions:'); writeln; for WriteCount := (Narrowfactor + 1) to (Narrowfactor + 6) do writeln(NarrowWords[WriteCount].toString); end; writeln('--------------------------------------'); writeln; Thread.sleep(1000); until lower_case_word = 'end'; end.
The project file crossword.oxygene
<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <PropertyGroup> <ProductVersion>3.5</ProductVersion> <OutputType>Exe</OutputType> <Configuration Condition="'$(Configuration)' == ''">Release</Configuration> <Name>Crossword</Name> <RootNamespace>org.me.crossword</RootNamespace> <AssemblyName>crossword</AssemblyName> <StartupClass /> <DefaultUses /> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <Optimize>true</Optimize> <OutputPath>.\bin\Release</OutputPath> <GenerateDebugInfo>False</GenerateDebugInfo> <GenerateMDB>False</GenerateMDB> <EnableAsserts>False</EnableAsserts> <TreatWarningsAsErrors>False</TreatWarningsAsErrors> <CaptureConsoleOutput>False</CaptureConsoleOutput> <StartMode>Project</StartMode> <RegisterForComInterop>False</RegisterForComInterop> <CpuType>anycpu</CpuType> <RuntimeVersion>v25</RuntimeVersion> <XmlDoc>False</XmlDoc> <XmlDocWarningLevel>WarningOnPublicMembers</XmlDocWarningLevel> <EnableUnmanagedDebugging>False</EnableUnmanagedDebugging> </PropertyGroup> <ItemGroup> <Reference Include="rt.jar" /> </ItemGroup> <ItemGroup> <Folder Include="Properties\" /> </ItemGroup> <ItemGroup> <Compile Include="crossword.pas"> <SubType>Code</SubType> </Compile> </ItemGroup> <Import Project="$(MSBuildExtensionsPath)\RemObjects Software\Oxygene\RemObjects.Oxygene.Cooper.targets" /> </Project>