As was foretold, we've added advertisements to the forums! If you have questions, or if you encounter any bugs, please visit this thread: https://forums.penny-arcade.com/discussion/240191/forum-advertisement-faq-and-reports-thread/
We're funding a new Acquisitions Incorporated series on Kickstarter right now! Check it out at https://www.kickstarter.com/projects/pennyarcade/acquisitions-incorporated-the-series-2

Giant Programming Clusterfuck++

1151618202163

Posts

  • bowenbowen How you doin'? Registered User regular
    edited April 2009
    Usually I recommend never using a const anywhere, and if you need a static variable like that, use a #define macro.

    This site really breaks it down:
    http://duramecho.com/ComputerInformation/WhyHowCppConst.html

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • NightslyrNightslyr Registered User regular
    edited April 2009
    bowen wrote: »
    Nightslyr wrote: »
    Hey guys, I was wondering if someone could point me in the right direction.

    A lot of the code I'm currently reading in my studies is C++ (Gang of Four book). I've had some experience with it in college, but some of the simple things confused me at the time, and still cause me to scratch my head now.

    I get the basics of argument passing. Pass by value and reference are pretty simple to understand. I get confused when constant reference enters the scene, as well as pointers.

    For the first, is only the reference constant? Can the value of the argument be changed/modified? How is this different from constant methods/functions?
    For the second, what's the difference between a pointer and a memory address?

    Are there any decent links/tutorials that go over this?

    I find this to be a good link to provide to people who have a difficulty with the whole notion of pointers and addresses:

    http://www.cplusplus.com/doc/tutorial/pointers.html

    http://www.cplusplus.com/doc/tutorial/constants.html

    Constants don't change, ever. So if you ever need a static value to be consistent, use a constant. Don't just throw const in front of things though, that's what retarded books and examples sometimes show you.

    Example: const float Pi = 3.14f; would be a good place to use a const.

    Well, I understand constants in and of themselves. But, like I asked above, what about constant reference? I.e.:
    void someFunction(const someObject& o);
    

    What part is constant? The reference to o, or o itself? And how does this behave? Is it similar to straight pass-by-reference?

    Thanks for the links, though. The pointer one looks especially good.

    Nightslyr on
    PSN/XBL/Nintendo/Origin/Steam: Nightslyr 3DS: 1607-1682-2948
    Switch: SW-3515-0057-3813 FF XIV: Q'vehn Tia
  • CmdPromptCmdPrompt Registered User regular
    edited April 2009
    For pointers, I always found that while I could understand what the tutorials, K&R, etc. were saying, I got confused in the implementation. I'd recommend playing around with making some pointers, dereferencing them, passing them, and so on.

    Of course, that applies to almost any concept in programming, but still.

    CmdPrompt on
    GxewS.png
  • bowenbowen How you doin'? Registered User regular
    edited April 2009
    Basically, what you're doing there, is essentially passing an address to data but making it so that it cannot be altered in the method. This is usually used when there's way too much data to copy, or it would take a long time to copy, so you let the method have access to the original object but you're telling it to not modify the data.

    Consts tend to be viral in my experience though.

    Damn, I still didn't answer your question Night: If I remember correctly, the address is constant, not the object itself.

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • EtheaEthea Registered User regular
    edited April 2009
    That should be a pass by reference that cannot be modified. So the object it self is constant, and you are passing by reference so you don't have to copy the object when calling the method.

    Ethea on
  • EvigilantEvigilant VARegistered User regular
    edited April 2009
    I'm hoping someone can help me.

    I have to create a client-server simulation. At each clock cycle(simulated), a job has to be placed into the queue, and then based on priority(1-3, 1 being highest) to be processed in order. It takes 3 clock cycles for a job to be finished, at which the program prints out the # of jobs finished and at what time.

    Right now, it'll do most of that, except prioritize and I'm having trouble with the time. After each job is finished I seem to lose 1 second, so that at say job # 15 I've lost 14 seconds.

    I've been staring at this for the last few hours and I can't seem to find where the time is giving me an issue, or how best to implement priority.
    
    /*-------------------------------------------
     * Edward Albrecht
     * CMSC 256
     * Spring 2009
     * Project 5
     * Purpose: Client-server simulation.
     * Input: A dat/text file with duration, cycles,
     *		  and jobs.
     * Output: # of jobs serviced @ time finished
     *		   Total jobs serviced and time system
     *		   stopped.
     ------------------------------------------*/
    import java.util.*;
    import java.io.*;
    import queue.Queue;
    
    class Proj5
    {
    	 /*************************Private Variables****************/
    	 	private static Job jobs; 
    	 	private static int jobServiced;
    	 	private static int time;
    	 	private static Queue<Job> queue;
    	 	private static Queue<Job> server;
    	 /*****************************Methods**********************
    	  * runProj
    	 /******************************Errors**********************/
    	 // throws IOException
    	 // Error caught by program: UnderFlowException
    	
    	
        public static void main(String[] args)throws IOException
        {
       		
            System.out.println("Project 5");
            System.out.println("Edward Albrecht");
            if(args.length == 1)	//if file is listed on command line
            {
            	runProj(args[0]);
            }
            else			      //else user must provide file
            {
            	String input = "";
            	Scanner scanuser = new Scanner(System.in);
            	System.out.println("");
            	System.out.print("Please enter a file to be used: ");
            	input = scanuser.next();
            	runProj(input);
            }
            
        }//end main
        
        /*----------------------------------
         * Class Job
         *    creates job objects.  
         *    Requires: Time, Priority
         *	Provided by instructor
         ---------------------------------*/
        private static class Job
        {
            private static int nextClient = 1;
            private int id,time,priority;
            public Job(int t, int p) { id = nextClient++; time = t; priority = p; }
            public int getId() { return id; }
            public int getTime() { return time; }
            public int getPriority() { return priority; }
            public String toString(){ return ("["+id+": "+time+","+priority+"]"); }
        }
    	
       /*--------------------------------
        * Method runProj
        *		requires a string to be used 
        *          for filereader
         -------------------------------*/
       private static void runProj(String filename)
       {
    	int time_job_has_been_in_server = 0;
    	System.out.println("");
    	System.out.println("Reading from file: "+filename);
            System.out.println("");
            try
            {
                BufferedReader br = new BufferedReader(new FileReader(filename));
                Scanner scan = new Scanner(br);
                    
                int duration = scan.nextInt()/2;
                int clock = scan.nextInt();
    	    jobServiced = 0;
    
                queue = new Queue<Job>();
                server = new Queue<Job>();
                    
                System.out.println("Service time: "+clock);
                System.out.println("Duration: "+duration);
                System.out.println("");
                
                for(time = 0; time <= duration; time++)   //clock cycle simulation
                {
                   	while(scan.hasNext())			//while there is a job needing to enter the system, place it into queue
                   	{
                   		int jobTime = scan.nextInt();
    	       		int jobPriority = scan.nextInt();
    	             	jobs = new Job(jobTime, jobPriority);
    	        	queue.enqueue(jobs);
    		}//end while
    		if(time == jobs.getTime())		//if time reaches a point where a job should enter the server
    		{
    			server.enqueue(queue.dequeue());
    		}	
                    if(server.isEmpty())			//if the server is empty
    		{
    		    	if(!queue.isEmpty())		//if there is a job in queue && the server is empty
    		        {
    		           	server.enqueue(queue.dequeue());
    		           	time_job_has_been_in_server = 0;	
    		        }
    		 }//end if
    		else
    		{
    		       	time_job_has_been_in_server++;
    		       	if(time_job_has_been_in_server == 3)	//has completed clock cycle
    		       	{
    		 	   server.dequeue();					//remove from server and increment jobServiced
    		       	   jobServiced++;
    		       	}
    		        if(server.isEmpty())					//if job in server is finished
    		        {
    			    System.out.println("Job # " + jobServiced + " done @ time " + (time+2));
    			    time_job_has_been_in_server = 0;
    			    server.enqueue(queue.dequeue());	//retrieve next job from queue
    			}
    		}//end else
    		}//end for
    	}//end try
            catch(Exception e)
            {
               	if(server.isEmpty() && queue.isEmpty())
               	{
               		System.out.println("");
               		System.out.println("Total jobs serviced: "+jobServiced);
    			System.out.println("System halted @ time "+time);
               	}
                else
                   	System.out.println("Error: "+e);
            }
    	}//end runProj
    }//end class proj5
    
    
    

    Evigilant on
    XBL\PSN\Steam\Origin: Evigilant
  • lazerbeardlazerbeard Registered User regular
    edited April 2009
    Nightslyr wrote: »
    bowen wrote: »
    Nightslyr wrote: »
    Hey guys, I was wondering if someone could point me in the right direction.

    A lot of the code I'm currently reading in my studies is C++ (Gang of Four book). I've had some experience with it in college, but some of the simple things confused me at the time, and still cause me to scratch my head now.

    I get the basics of argument passing. Pass by value and reference are pretty simple to understand. I get confused when constant reference enters the scene, as well as pointers.

    For the first, is only the reference constant? Can the value of the argument be changed/modified? How is this different from constant methods/functions?
    For the second, what's the difference between a pointer and a memory address?

    Are there any decent links/tutorials that go over this?

    I find this to be a good link to provide to people who have a difficulty with the whole notion of pointers and addresses:

    http://www.cplusplus.com/doc/tutorial/pointers.html

    http://www.cplusplus.com/doc/tutorial/constants.html

    Constants don't change, ever. So if you ever need a static value to be consistent, use a constant. Don't just throw const in front of things though, that's what retarded books and examples sometimes show you.

    Example: const float Pi = 3.14f; would be a good place to use a const.

    Well, I understand constants in and of themselves. But, like I asked above, what about constant reference? I.e.:
    void someFunction(const someObject& o);
    

    What part is constant? The reference to o, or o itself? And how does this behave? Is it similar to straight pass-by-reference?

    Thanks for the links, though. The pointer one looks especially good.


    o is const, making the reference to o const wouldn't really make sense, as you cannot change what the reference to o references anyway.

    In practice, they work similarly to a const*, but they provide some more convenient syntax, you cannot actually work with the pointer, which is nice if you don't need to modify the pointer inside the function. Because of this, they are "safer" than pointers, but you get the same benefit you would get by passing a pointer into a function, rather than pass by value and requiring a copy.

    For instance
    void someFunction(const someObject& o);
    and
    void someFunction(const someObject* const o);

    would get you the same thing, but in the bottom one you would have to use the -> operator, rather than the . operator.

    Just remember that references still do work like pointers, so

    someObject& someFunction(void);

    is dangerous if the object you are returning was created inside the function, as it will have fallen out of scope by the time you return it, meaning that the reference is pointing to bad memory.

    lazerbeard on
  • Mr.FragBaitMr.FragBait Registered User regular
    edited April 2009
    RandomEngy wrote: »
    Yeah well all it needs to deal with is subtitle tracks for movies, which aren't going to be more than a few KB. Don't need to overengineer it.
    You're telling me don't overengineer it? Have you been reading what I've been telling Lork? Just kiddin' :P

    Mr.FragBait on
  • InfidelInfidel Heretic Registered User regular
    edited April 2009
    lazerbeard wrote: »
    Just remember that references still do work like pointers, so

    someObject& someFunction(void);

    is dangerous if the object you are returning was created inside the function, as it will have fallen out of scope by the time you return it, meaning that the reference is pointing to bad memory.

    Only if you're returning a someObject that is on the stack and not allocated dynamically in the function, like with a new or such.

    Infidel on
    OrokosPA.png
  • lazerbeardlazerbeard Registered User regular
    edited April 2009
    Right, but if you allocate it dynamically and return by reference, unless something else actually holds the pointer (like a class or such) that memory won't be able to be freed in that case. Also if you do return by reference of an object that was allocated dynamically, then delete that memory, the reference will of course be invalidated as well.

    lazerbeard on
  • His CorkinessHis Corkiness Registered User regular
    edited April 2009
    You read pointers and references right-to-left.

    'foo &' is a reference to a foo. You can change the foo object.
    'const foo &' is a reference to a foo that is const. You can't change the foo object.
    'foo & const' is a const reference to a foo. This is redundant though as references are const by default.
    'const foo * const' is a const pointer to a foo that is const. You can't change where the pointer points to, nor the thing that it points at.

    Edit: And if you want to code in modern, idiomatic C++, you'll use const wherever appropriate and stay away from #defines. It's also much easier to code using const from the beginning, than to retroactively add it.

    His Corkiness on
  • ZackSchillingZackSchilling Registered User regular
    edited April 2009
    lazerbeard wrote: »
    Right, but if you allocate it dynamically and return by reference, unless something else actually holds the pointer (like a class or such) that memory won't be able to be freed in that case. Also if you do return by reference of an object that was allocated dynamically, then delete that memory, the reference will of course be invalidated as well.

    To make it concrete for people:
    GiantObject* orsonwells = new GiantObject();
    GiantObject* chrisfarley = new GiantObject();
    GiantObject* davidspade = chrisfarley;
    
    orsonwells = null;
    del chrisfarley;
    chrisfarley = null;
    

    At the end of this code snippet:

    orsonwells points to nothing, but the object originally pointed to is still hanging around using up RAM with no way to get at it for use or deletion.

    chrisfarley's object has been deallocated and is no longer hanging around. The variable is now pointing nowhere.

    davidspade used to point at chrisfarley's object, but when chrisfarley's object got deleted, davidspade kept pointing there. If he tried to access his object, it wouldn't be there anymore and the code will fail.

    ZackSchilling on
    ghost-robot.jpg
  • SmasherSmasher Starting to get dizzy Registered User regular
    edited April 2009
    Evigilant wrote: »
    I'm hoping someone can help me.

    I have to create a client-server simulation. At each clock cycle(simulated), a job has to be placed into the queue, and then based on priority(1-3, 1 being highest) to be processed in order. It takes 3 clock cycles for a job to be finished, at which the program prints out the # of jobs finished and at what time.

    Right now, it'll do most of that, except prioritize and I'm having trouble with the time. After each job is finished I seem to lose 1 second, so that at say job # 15 I've lost 14 seconds.

    I've been staring at this for the last few hours and I can't seem to find where the time is giving me an issue, or how best to implement priority.

    For priority you can just use a priority queue in place of the queue you're using now. I'm not sure what's causing the timing bug, but a few thoughts/questions about your code:

    The idea is that the priority queue determines the order of the jobs in the queue, but jobs only enter the queue when time == job.getTime(), right? I'm pretty sure that's what's intended, but best to be sure about it.

    You currently read the input file (with the list of jobs) inside the clock cycle loop. Since that only needs to be done once you should probalby place it before the loop.

    The if block "if(time == jobs.getTime()){...}" should iterate over the queue instead. Currently it's only looking at the last job you read from the file.

    If the server queue is empty you take a job from the queue regardless of the job's specified time. Is this intended?

    The line:
    System.out.println("Job # " + jobServiced + " done @ time " + (time+2));
    is only printed if the server is empty; it seems like it should be printed even if it's not. Also, why time+2? The job is already done so it seems you should be able to use the current time.

    Smasher on
  • InfidelInfidel Heretic Registered User regular
    edited April 2009
    lazerbeard wrote: »
    Right, but if you allocate it dynamically and return by reference, unless something else actually holds the pointer (like a class or such) that memory won't be able to be freed in that case. Also if you do return by reference of an object that was allocated dynamically, then delete that memory, the reference will of course be invalidated as well.

    The reference you return is your pointer, if you take the address of it. You can delete the object that was returned as a ref just fine still.

    Is it a recommended way of doing things though? I doubt it, I'd use a pointer myself. I was just pointing out however that it's incorrect to say that you cannot return a new object as a reference.

    Infidel on
    OrokosPA.png
  • exisexis Registered User regular
    edited April 2009
    To be up front, this is in relation to an assignment. I'm not really looking for anyone to do my homework, but thought I should be clear in case this is crossing the line.

    For a plugin we're writing for Eclipse, we're looking to record a bunch of metric data, store it away, and use it later to generate software metrics. We have a pretty solid idea of what we're recording, and how we're planning on getting it. The one thing that we can't come up with an elegant solution for is how we're going to deal with lines of code. For some of the info we'd like to pull out of this data, we want to have an idea of the evolution of code, including things along the lines of "this line was edited a bazillion times". We don't have any intention of storing the actual code, we just want information about it.

    Now, where we're stuck is the obvious issue: line #34 is no longer line #34 if you insert ten new lines above it. My first idea was to build a linked list of lines, each of which has some unique ID. New lines inserted into code at random points would be put into the list, and any time an existing line was updated we could just look at it's unique ID. In the DB, lines would be stored with 'next' attributes just like a regular linked list (not sure if this would be the best way to go about it). But I'm concerned about performance. For every file opened, we'll have to query the DB and build a linked list for every line in the file. This software should be usable in a professional environment, so we don't want any issues with arbitrarily large files. Updating the DB with new data probably wouldn't be too terrible since we'd only have to insert any new lines, change some 'next' attributes, and modify altered lines.

    So... Is this an absolutely terrible way of going about this? How does versioning software (SVN, CVS, etc.) deal with synchronization issues like this? I imagine we could work a similar solution.

    exis on
  • lazerbeardlazerbeard Registered User regular
    edited April 2009
    whoops, you're right, I wasn't thinking there. Its still an awkward way to go about things, like you said, a pointer would be much more appropriate there, unless you are trying to confuse yourself two months later.

    lazerbeard on
  • zeenyzeeny Registered User regular
    edited April 2009
    exis wrote: »
    we want to have an idea of the evolution of code, including things along the lines of "this line was edited a bazillion times". We don't have any intention of storing the actual code, we just want information about it.

    Line numbers are meaningful only if you also mention a software revision number.
    So... Is this an absolutely terrible way of going about this? How does versioning software (SVN, CVS, etc.) deal with synchronization issues like this? I imagine we could work a similar solution.

    Snapshots & historical data.


    Dare I ask what information do you believe that the number of time "a line" was "edited" brings you? Because "a line" is really not a factor in code design/evolution.

    zeeny on
  • NightslyrNightslyr Registered User regular
    edited April 2009
    I think I may have designed myself into a corner.

    I'm still working on my ASP.NET game, specifically the combat portion. I need to somehow write the outcome of an attack to the screen. The problem is that my attack object(s) are nested within character objects. I'm not sure how to best pass the server control down to the attack so it can be written to. Similarly, there isn't a clean way to have the attacks return a value since they're currently written with a void return type. I'd like to avoid using some sort of singleton noteboard if I can help it.

    I'm thinking I may need to rewrite the whole damn thing, as it looks to be pretty clunky. That said, I'm going to post a lot of my code so I can get some good feedback and/or guidance.

    The key class(es) revolve around the notion of a Character. The Character is the base class for both user-controlled characters (the PlayerCharacter) and computer-controlled characters (the Enemy). After talking to BlueSquare in PMs about the best way to clean up my class interfaces and perhaps simplify storing/retrieving Character data from the DB, I followed his suggestion and broke Character into smaller classes/objects. So, here's what I have for that:

    Character abstract base class:
    public abstract class Character
    {
        protected CharAttacks attacks;
        protected CharBio bio;
        protected CharInv inv;
        protected CharStats stats;
    
        public Character(CharAttacks attacks, CharBio bio, CharInv inv, CharStats stats)
        {
            this.attacks = attacks;
            this.bio = bio;
            this.inv = inv;
            this.stats = stats;
        }
    
        public void Attack(string attackName)
        {
            this.attacks.Attack(attackName);
        }
    
        public string Name
        {
            get { return this.bio.Name; }
            set { this.bio.Name = value; }
        }
    
        public string Desc
        {
            get { return this.bio.Desc; }
            set { this.bio.Desc = value; }
        }
    
        public string Gender
        {
            get { return this.bio.Gender; }
            set { this.bio.Gender = value; }
        }
    
        public int Level
        {
            get { return this.stats.Level; }
            set { this.stats.Level = value; }
        }
    
        public int TotalHP
        {
            get { return this.stats.TotalHP; }
            set { this.stats.TotalHP = value; }
        }
    
        public int TotalTP
        {
            get { return this.stats.TotalTP; }
            set { this.stats.TotalTP = value; }
        }
    
        public int CurrentHP
        {
            get { return this.stats.CurrentHP; }
            set { this.stats.CurrentHP = value; }
        }
    
        public int CurrentTP
        {
            get { return this.stats.CurrentTP; }
            set { this.stats.CurrentTP = value; }
        }
    
        public int DMG
        {
            get { return this.stats.DMG; }
            set { this.stats.DMG = value; }
        }
    
        public float DMGModifier
        {
            get { return this.stats.DMGModifier; }
            set { this.stats.DMGModifier = value; }
        }
    
        public float ChanceToHit
        {
            get { return this.stats.ChanceToHit; }
            set { this.stats.ChanceToHit = value; }
        }
    
        public ICharacterClass Class
        {
            get { return this.stats.CharClass; }
        }
    
        public List<Attack> Attacks
        {
            get { return this.attacks.Attacks; }
        }
    
        public List<Loot> Inventory
        {
            get { return this.inv.Loot; }
            set { this.inv.Loot = value; }
        }
    
        public int EXP
        {
            get { return this.stats.EXP; }
            set { this.stats.EXP = value; }
        }
    
        public float Money
        {
            get { return this.inv.Money; }
            set { this.inv.Money = value; }
        }
    }
    

    The smaller 'chunk' classes that make up a Character -

    CharAttacks (the most relevant to my problem):
    public class CharAttacks
    {
        private List<Attack> attacks;
    
        public CharAttacks(List<Attack> attacks)
        {
            this.attacks = attacks;
        }
    
        public void AddAttack(Attack attack)
        {
            this.attacks.Add(attack);
        }
    
        public void Attack(string attackName)
        {
            Attack current = this.attacks.Find(delegate(Attack att) { return att.Name == attackName; });
            current.ExecuteAttack();
        }
    
        public List<Attack> Attacks
        {
            get { return this.attacks; }
        }
    }
    

    CharBio:
    public class CharBio
    {
        private string name;
        private string gender;
        private string desc;
    
        public CharBio(string name, string gender, string desc)
        {
            this.name = name;
            this.gender = gender;
            this.desc = desc;
        }
    
        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }
    
        public string Gender
        {
            get { return this.gender; }
            set { this.gender = value; }
        }
    
        public string Desc
        {
            get { return this.desc; }
            set { this.desc = value; }
        }
    }
    

    CharInv:
    public class CharInv
    {
        private static int maxItems = 30;
    
        private List<Loot> loot;
        private float money;
    
        public CharInv(List<Loot> loot, float money)
        {
            this.loot = loot;
            this.money = money;
        }
    
        public List<Loot> Loot
        {
            get { return this.loot; }
            set { this.loot.Add(value[0]); }
        }
    
        public float Money
        {
            get { return this.money; }
            set { this.money = value; }
        }
    }
    

    CharStats:
    public class CharStats
    {
        private static int maxLevel = 27;
    
        private int level;
        private int totalHP;
        private int totalTP;
        private int currentHP;
        private int currentTP;
        private int exp;
        private int dmg;
        private float dmgModifier;
        private float chanceToHit;
        private ICharacterClass charClass;
    
        public CharStats(int level, int totalHP, int totalTP, int currentHP, int currentTP, int exp, int dmg, float dmgModifier, float chanceToHit, ICharacterClass charClass)
        {
            this.level = level;
            this.totalHP = totalHP;
            this.totalTP = totalTP;
            this.currentHP = currentHP;
            this.currentTP = currentTP;
            this.exp = exp;
            this.dmg = dmg;
            this.dmgModifier = dmgModifier;
            this.chanceToHit = chanceToHit;
            this.charClass = charClass;
        }
    
        public int Level
        {
            get { return this.level; }
            set { this.level = value; }
        }
    
        public int TotalHP
        {
            get { return this.totalHP; }
            set { this.totalHP = value; }
        }
    
        public int TotalTP
        {
            get { return this.totalTP; }
            set { this.totalTP = value; }
        }
    
        public int CurrentHP
        {
            get { return this.currentHP; }
            set { this.currentHP = value; }
        }
    
        public int CurrentTP
        {
            get { return this.currentTP; }
            set { this.currentTP = value; }
        }
    
        public int EXP
        {
            get { return this.exp; }
            set { this.exp = value; }
        }
    
        public int DMG
        {
            get { return this.dmg; }
            set { this.dmg = value; }
        }
    
        public float DMGModifier
        {
            get { return this.dmgModifier; }
            set { this.dmgModifier = value; }
        }
    
        public float ChanceToHit
        {
            get { return this.chanceToHit; }
            set { this.chanceToHit = value; }
        }
    
        public ICharacterClass CharClass
        {
            get { return this.charClass; }
        }
    }
    

    ICharacterClass:
    public interface ICharacterClass
    {
        int HP { get; }
        int TP { get; }
        int BaseDMG { get; }
        int HPMultiplier { get; }
        int TPMultiplier { get; }
        int BaseDMGMultiplier { get; }
    }
    

    And an example of a character class:
    public class Hacker : ICharacterClass
    {
        private int hitPoints = 10;
        private int techPoints = 25;
        private int baseDmg = 2;
        private int hpMultiplier = 2;
        private int tpMultiplier = 4;
        private int baseDmgMultiplier = 2;
    
        public Hacker() { }
    
        public int HP
        {
            get
            {
                return this.hitPoints;
            }
        }
    
        public int TP
        {
            get
            {
                return this.techPoints;
            }
        }
    
        public int BaseDMG
        {
            get
            {
                return this.baseDmg;
            }
        }
    
        public int HPMultiplier
        {
            get
            {
                return this.hpMultiplier;
            }
        }
    
        public int TPMultiplier
        {
            get
            {
                return this.tpMultiplier;
            }
        }
    
        public int BaseDMGMultiplier
        {
            get
            {
                return this.baseDmgMultiplier;
            }
        }
    }
    

    Phew! And we haven't even made it to the PlayerCharacter and Enemy yet!

    PlayerCharacter:
    public class PlayerCharacter : Character
    {
        private Equipment equipment;
    
        public PlayerCharacter(CharAttacks attacks, CharBio bio, CharInv inv, CharStats stats, Equipment equipment) :
            base(attacks, bio, inv, stats)
        {
            this.equipment = equipment;
        }
    
        public void LevelUp()
        {
            this.stats.TotalHP += (this.stats.TotalHP / 10) * this.stats.CharClass.HPMultiplier;
            this.stats.TotalTP += (this.stats.TotalTP / 10) * this.stats.CharClass.TPMultiplier;
            this.stats.DMGModifier += 0.10f;
            this.stats.ChanceToHit += 0.05f;
            this.stats.DMG += (this.stats.DMG / 10) * this.stats.CharClass.BaseDMGMultiplier;
    
            if ((this.stats.Level % 3) == 0)
            {
                try
                {
                    AttackRegistry attackReg = new AttackRegistry();
                    Attack newAttack = attackReg.GetAttack(this);
                    this.attacks.AddAttack(newAttack);
                }
                catch (Exception e)
                {
                    Console.Write(e.Message);
                }
            }
        }
    
        public Weapon LeftHand
        {
            get { return this.equipment.LeftHand; }
            set { this.equipment.LeftHand = value; }
        }
    
        public Weapon RightHand
        {
            get { return this.equipment.RightHand; }
            set { this.equipment.RightHand = value; }
        }
    
        public Armor Armor
        {
            get { return this.equipment.Armor; }
            set { this.equipment.Armor = value; }
        }
    }
    

    Enemy:
    public class Enemy : Character
    {
        public Enemy(CharAttacks attacks, CharBio bio, CharInv inv, CharStats stats) : base(attacks, bio, inv, stats) { }
    }
    

    ...

    Looking at it now, it certainly looks a bit over-engineered, but I'm not quite sure how to trim the fat. Attacks are called like thus (again, thanks to BlueSquare's help for getting something to work):
    protected void AttackButtonClick(object sender, EventArgs e)
    {
        Button button = (Button)sender;
        string attackName = button.CommandName;
        this.PC.Attack(attackName);
    }
    
    /* ... */
    
    Table attackGrid = new Table();
    TableRow tr = new TableRow();
    attackGrid.Rows.Add(tr);
    
    int attackCount = this.PC.Attacks.Count;
    
    for (int i = 0; i < attackCount; i++)
    {
        Button attackButton = new Button();
        attackButton.CommandName = this.PC.Attacks.ElementAt(i).Name;
        attackButton.Text = attackButton.CommandName;
        attackButton.Click += new EventHandler(this.AttackButtonClick);
    
        TableCell td = new TableCell();
        td.Controls.Add(attackButton);
        tr.Cells.Add(td);
    }
    

    I think that sufficiently shows why I'm having a hard time figuring out how output an attack's result to the screen, given how deeply they're buried.

    Should I just scrap it all and start again? Are there any tips anyone can give me on how to reduce the bloat? I'm thinking that maybe some of the unchanging core bits (character class data, etc) should be stored as XML and then read into the objects. I'm also not sure how to handle the attack objects themselves. A hacker shouldn't have access to a soldier's attacks (and vice versa), but I'm not sure if enforcing that by subclassing Attack is the way to go.

    Nightslyr on
    PSN/XBL/Nintendo/Origin/Steam: Nightslyr 3DS: 1607-1682-2948
    Switch: SW-3515-0057-3813 FF XIV: Q'vehn Tia
  • bowenbowen How you doin'? Registered User regular
    edited April 2009
    Couldn't you create an outcome class of some sort with all the variables you want?

    So that your player classes' attack returns an outcome object that you can use.

    Outcome attackOutcome = Player1.Attack(...); ?

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • NightslyrNightslyr Registered User regular
    edited April 2009
    bowen wrote: »
    Couldn't you create an outcome class of some sort with all the variables you want?

    So that your player classes' attack returns an outcome object that you can use.

    Outcome attackOutcome = Player1.Attack(...); ?

    I've thought about that, actually, and have the skeleton of an attackMessenger class written up. I'm just not sure how to catch that return value in the system, given my sketchy knowledge of ASP's/C#'s event model.

    Wait...storing it in a session may do what I want. Would that be good or 'proper' design, though? I mean, it kinda messes with scope (it'd go from being nested a few levels down - inside an Attack object once it performs its Execute method - upon object creation to essentially top-level once stored in the session).

    Nightslyr on
    PSN/XBL/Nintendo/Origin/Steam: Nightslyr 3DS: 1607-1682-2948
    Switch: SW-3515-0057-3813 FF XIV: Q'vehn Tia
  • bowenbowen How you doin'? Registered User regular
    edited April 2009
    I don't know. It seems like you're vastly over-thinking this. Scope is one thing, but you're talking about communicating data between an event and a user or a class and another class.

    From what I've understood from the brief browse of your code and old posts.

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • NightslyrNightslyr Registered User regular
    edited April 2009
    bowen wrote: »
    I don't know. It seems like you're vastly over-thinking this. Scope is one thing, but you're talking about communicating data between an event and a user or a class and another class.

    From what I've understood from the brief browse of your code and old posts.

    I probably am over-thinking it. I tend to do that. I just have it in my mind that I must have well-formed, professional code that takes into account the proper separation of application tiers and whatnot.

    The game is actually a giant learning exercise so I can learn proper OO techniques and how to build something the 'right' way. It probably won't go on my resume, but I'm trying to treat it as if it were.

    Nightslyr on
    PSN/XBL/Nintendo/Origin/Steam: Nightslyr 3DS: 1607-1682-2948
    Switch: SW-3515-0057-3813 FF XIV: Q'vehn Tia
  • bowenbowen How you doin'? Registered User regular
    edited April 2009
    OO is great until the design gets in the way of productivity. At the expense of having to destroy all your progress, I'd say skip whatever notion of level of scope you're trying to comprehend and figure out the implementation that'd give you the solution to your problem.

    Theory and practice takes a backseat to usability. IMO.

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • AntishowAntishow Registered User regular
    edited April 2009
    Ok, so I follow that this is how I instantiate a new NSMutableArray...
    myArray = [[NSMutableArray alloc] init];
    

    I thought I could give it some default values by doing this....
    myArray = [[NSMutableArray alloc] initWithObjects:@"A String!",@"zomg another one!",@"One more"];
    

    But that won't compile. What am I missing? Do I just need to add them after I build the array?

    Antishow on
  • jackaljackal Fuck Yes. That is an orderly anal warehouse. Registered User regular
    edited April 2009
    Bill the robot is pretty awesome. It's like a game version of a really limited logo implementation.

    Edit: Dude, don't make me rewrite the whole program if I have a bug!

    jackal on
  • AntishowAntishow Registered User regular
    edited April 2009
    Thanks! That's actually exactly what I was trying to accomplish! I was teaching an elementary school computer class and logo was a little over their heads, so Bill was born.

    That was a few years ago. I keep trying to make Bill2, but I'm caught in this cycle where I need to learn new techniques to make what I want, but then that expanded knowledge raises my personal standards, so then I need to learn MORE new techniques, and I end up never finishing anything.

    edit: Ugh, yeah I know. I'm so stupid. I lost the source a few years ago, so I can't fix it QQ

    Antishow on
  • KrisKris Registered User regular
    edited April 2009
    Antishow wrote: »
    Ok, so I follow that this is how I instantiate a new NSMutableArray...
    myArray = [[NSMutableArray alloc] init];
    

    I thought I could give it some default values by doing this....
    myArray = [[NSMutableArray alloc] initWithObjects:@"A String!",@"zomg another one!",@"One more"];
    

    But that won't compile. What am I missing? Do I just need to add them after I build the array?

    After looking at the documentation, I believe you're missing a nil at the end of your parameter list. The doc says the parameter list should be "a comma-separated list of objects ending with nil." Which would lead me to believe you're code should look like:
    myArray = [[NSMutableArray alloc] initWithObjects:@"A String!", @"zomg another one!", @"One more", nil];
    

    Kris on
  • InfidelInfidel Heretic Registered User regular
    edited April 2009
    Nightslyr wrote: »
    bowen wrote: »
    I don't know. It seems like you're vastly over-thinking this. Scope is one thing, but you're talking about communicating data between an event and a user or a class and another class.

    From what I've understood from the brief browse of your code and old posts.

    I probably am over-thinking it. I tend to do that. I just have it in my mind that I must have well-formed, professional code that takes into account the proper separation of application tiers and whatnot.

    The game is actually a giant learning exercise so I can learn proper OO techniques and how to build something the 'right' way. It probably won't go on my resume, but I'm trying to treat it as if it were.

    There's a lot of your stuff all over, so forgive me if I forget something or misunderstood it.

    You have a main game engine that knows pretty much all whats going on right? It can reference the web session, the game objects and players, etc. And the problem is when you pass things down and dig deep enough to reach something like a doAttack method, that method doesn't know about things like the web session.

    Which is good, because it shouldn't. So you're doing it right, but getting stuck on what is the next step? Pass the results back up! Instead of firing your events to eventually get an attack resolved and wanting to just jam the result text straight into a session, you should be unwinding things and somehow getting that message in a general way back up to the main engine which DOES know things about sessions and other players and such.

    Many ways to do things, but whatever you do, you should not tie parts of your code and classes to a doAttack type method that don't have anything directly to do with resolving an attack. :) (the players/npc's involved, the weapon, etc.)

    I could probably explain this a hell of a lot better with an example but I don't have much time atm.

    Infidel on
    OrokosPA.png
  • EvigilantEvigilant VARegistered User regular
    edited April 2009
    Smasher wrote: »
    For priority you can just use a priority queue in place of the queue you're using now. I'm not sure what's causing the timing bug, but a few thoughts/questions about your code:

    The idea is that the priority queue determines the order of the jobs in the queue, but jobs only enter the queue when time == job.getTime(), right? I'm pretty sure that's what's intended, but best to be sure about it.

    You currently read the input file (with the list of jobs) inside the clock cycle loop. Since that only needs to be done once you should probalby place it before the loop.

    The if block "if(time == jobs.getTime()){...}" should iterate over the queue instead. Currently it's only looking at the last job you read from the file.

    If the server queue is empty you take a job from the queue regardless of the job's specified time. Is this intended?

    The line:
    System.out.println("Job # " + jobServiced + " done @ time " + (time+2));
    is only printed if the server is empty; it seems like it should be printed even if it's not. Also, why time+2? The job is already done so it seems you should be able to use the current time.

    Note: this is for my homework, but I figured since I've done most of the coding and I just have a few simple errors that I can't figure out, it's best to ask someone for guidance. I'm not asking for the actual code, I'm just asking for someone to help guide me how to solve this problem, where the issue exists, and what steps I might be able to take to remedy the problem.

    We have to use a .jar file he's provided that has the methods for our queue's.

    I've changed the way the server pulls the job from the queue. First I've created a new Job called thisJob and I'm using that to dequeue the result each time.

    for the time+2, jobs must remain in the server for a complete clock cycle for it to be considered serviced for one unit of time. Therefor a job is always c+2 cycles to enter the system, be serviced, and then leave. I'm not sure if I'm implementing that right, since the issue I have now is with my timing.

    The last if statement where it checks if the server is empty, above it, each job requires 3 clock cycles inside the server, and then it gets pushed out on the next tick. So for the first job, it enters the system at tick 1, waits in the server for 3 ticks, then exits the server on the next tick. Once it exits, the program then checks if the server is empty (which it will be at this time), then prints that the job # is done @ x time.

    So for example, the program should run like this
    0 (jobs are created and placed into queue)
    1 (7 jobs are loaded into the server queue)
    2 (the first job in the server is being worked on, the other 6 are waiting)
    3 (the first job is being worked on, other 6 are waiting)
    4 (the first job is done and job # 4 2 enters the server queue and goes ahead of job # 6, since it has a higher priority)
    5 (the first job exits the server and prints, while the 2nd job enters the server)
    6 (the second job is being worked on)
    7 (the 2nd job is being worked on, the rest are waiting)
    8 (the 2nd job is being worked on)
    9 (the 2nd job finishes and prints, the 3rd job enters the server)
    10 (job # 9 enters the server queue and goes ahead of job #4, since it has a higher priority)
    so on and so on

    So right now, it prints off all 15 jobs without any difference in priority or time. It needs to print the jobs off based on both time + priority, so for example, the output needs to look like this:
    job # 1 done @ time 5
    job # 2 done @ time 9
    job # 3 done @ time 13
    job # 9 done @ time 17
    job # 4 done @ time 21
    job # 5 done @ time 25
    job #13 done @ time 29
    job # 6 done @ time 33
    job # 8 done @ time 37
    job #12 done @ time 41
    job # 7 done @ time 45
    job #10 done @ time 49
    job #11 done @ time 53
    job #15 done @ time 57
    job #14 done @ time 61
    Total jobs serviced: 15
    System halted @ time 61; all jobs were serviced

    Currently I'm having trouble how to establish that at this particular moment in time, if it equals the time the job should enter the server, go into the server if it's also the highest priority. I've tried creating other Queue<Job> queue1-3 to separate the priority of the jobs, but it seems to only print out one job if I do it that way(most likely an error on my part).

    I've tried adding above the if statements for priority if(time == thisJob.getTime()) {.......}, but it prints the 2nd job and only the 2nd job.
    file being input:
    200
    3
    1 1
    1 1
    1 1
    1 2
    1 2
    1 2
    1 3
    4 2
    10 1
    18 3
    18 3
    20 2
    22 1
    22 3
    51 1
    
    
    
    
    private static void runProj(String filename)
    {
    	int time_job_has_been_in_server = 0;
    	System.out.println("");
    	System.out.println("Reading from file: "+filename);
            System.out.println("");
            try
            {
            	BufferedReader br = new BufferedReader(new FileReader(filename));
                    Scanner scan = new Scanner(br);
                    
                int fileTime = scan.nextInt();
                int clock = scan.nextInt();
    	    jobServiced = 0;
    	    int duration = fileTime/2;
                queue = new Queue<Job>();
                server = new Queue<Job>();
                    
                System.out.println("Service time: "+clock);
                System.out.println("Duration: "+fileTime);
                System.out.println("");
    while(scan.hasNext())   			//while there is a job needing to enter the system
    {
        int jobTime = scan.nextInt();
        int jobPriority = scan.nextInt();
        jobs = new Job(jobTime, jobPriority);
        queue.enqueue(jobs);
    }
                
    while(time <= duration && scan.hasNext() || !queue.isEmpty() || !server.isEmpty())
    {
        if(server.isEmpty())			//if the server is empty
        {
    	if(!queue.isEmpty())		//if there is a job in queue && the server is empty
    	{
    	   thisJob = queue.dequeue();
    	   if(thisJob.getPriority() == 1)
    	   {
    	      server.enqueue(thisJob);
    	      time_job_has_been_in_server = 0;
    	   }
    	  if(thisJob.getPriority() == 2)
    	  {
    	      server.enqueue(thisJob);
    	      time_job_has_been_in_server = 0;
    	  }
    	   if(thisJob.getPriority() == 3)
    	   {
    		server.enqueue(thisJob);
    		time_job_has_been_in_server = 0;
    	  }
            }
          }//end if
         else
          {
    	  time_job_has_been_in_server++;
    	  if(time_job_has_been_in_server == 3)	//has completed clock cycle
              {
    	      server.dequeue();					//remove from server and increment jobServiced
    	      jobServiced++;
    	   }
    	   if(server.isEmpty())					//if job in server is finished
    	   {
    	      System.out.println("Job # " + thisJob.getId() + " done @ time " + (time+2));
    	      time_job_has_been_in_server = 0;
    	  }
          }//end else
          time++;
         if(time >= (duration*2))
    	throw new Exception ("Error: Infinite Loop");
    }//end while
    }//end runProj
    
    So far my output looks like this:
    Reading from file: test.dat

    Service time: 3
    Duration: 200

    Job # 1 done @ time 5
    Job # 2 done @ time 9
    Job # 3 done @ time 13
    Job # 4 done @ time 17
    Job # 5 done @ time 21
    Job # 6 done @ time 25
    Job # 7 done @ time 29
    Job # 8 done @ time 33
    Job # 9 done @ time 37
    Job # 10 done @ time 41
    Job # 11 done @ time 45
    Job # 12 done @ time 49
    Job # 13 done @ time 53
    Job # 14 done @ time 57
    Job # 15 done @ time 61

    Total jobs serviced: 15
    System halted @ time 61; all jobs were serviced

    I'm stuck and I can't rationalize how to solve this issue.

    Evigilant on
    XBL\PSN\Steam\Origin: Evigilant
  • exisexis Registered User regular
    edited April 2009
    zeeny wrote: »
    Dare I ask what information do you believe that the number of time "a line" was "edited" brings you? Because "a line" is really not a factor in code design/evolution.

    The intention of the plugin is to provide process metrics about projects. Since there isn't a definitive list of 'useful' process metrics, our approach is to measure a whole bunch of stuff, then provide an API for the end user to pull whatever they want out of it. Something we're planning on recording is 'edits', which we're defining as a single contained block of code altered, deleted or added. Along with other information about edits, we were planning on storing the line(s) they occurred on.

    From this we can extract information like "Bob added this method on this date. It was 30 lines long. John edited that method later, removed 15 lines of code and modified another 10" etc etc. That's would be a specific usage of actual lines, but first and foremost we want to remember line positions to give us a means of comparison when code is changed (eg. "this happened at line 40"). It's really not up to us what information people want to pull out of this, or whether they use it to draw some sort of conclusion about development. But our purpose is to make the information available.

    exis on
  • SmasherSmasher Starting to get dizzy Registered User regular
    edited April 2009
    Evigilant wrote: »
    Note: this is for my homework, but I figured since I've done most of the coding and I just have a few simple errors that I can't figure out, it's best to ask someone for guidance. I'm not asking for the actual code, I'm just asking for someone to help guide me how to solve this problem, where the issue exists, and what steps I might be able to take to remedy the problem.

    We have to use a .jar file he's provided that has the methods for our queue's.

    I've changed the way the server pulls the job from the queue. First I've created a new Job called thisJob and I'm using that to dequeue the result each time.

    for the time+2, jobs must remain in the server for a complete clock cycle for it to be considered serviced for one unit of time. Therefor a job is always c+2 cycles to enter the system, be serviced, and then leave. I'm not sure if I'm implementing that right, since the issue I have now is with my timing.

    The last if statement where it checks if the server is empty, above it, each job requires 3 clock cycles inside the server, and then it gets pushed out on the next tick. So for the first job, it enters the system at tick 1, waits in the server for 3 ticks, then exits the server on the next tick. Once it exits, the program then checks if the server is empty (which it will be at this time), then prints that the job # is done @ x time.

    So for example, the program should run like this
    0 (jobs are created and placed into queue)
    1 (7 jobs are loaded into the server queue)
    2 (the first job in the server is being worked on, the other 6 are waiting)
    3 (the first job is being worked on, other 6 are waiting)
    4 (the first job is done and job # 4 2 enters the server queue and goes ahead of job # 6, since it has a higher priority)
    5 (the first job exits the server and prints, while the 2nd job enters the server)
    6 (the second job is being worked on)
    7 (the 2nd job is being worked on, the rest are waiting)
    8 (the 2nd job is being worked on)
    9 (the 2nd job finishes and prints, the 3rd job enters the server)
    10 (job # 9 enters the server queue and goes ahead of job #4, since it has a higher priority)
    so on and so on

    So right now, it prints off all 15 jobs without any difference in priority or time. It needs to print the jobs off based on both time + priority, so for example, the output needs to look like this:
    job # 1 done @ time 5
    job # 2 done @ time 9
    job # 3 done @ time 13
    job # 9 done @ time 17
    job # 4 done @ time 21
    job # 5 done @ time 25
    job #13 done @ time 29
    job # 6 done @ time 33
    job # 8 done @ time 37
    job #12 done @ time 41
    job # 7 done @ time 45
    job #10 done @ time 49
    job #11 done @ time 53
    job #15 done @ time 57
    job #14 done @ time 61
    Total jobs serviced: 15
    System halted @ time 61; all jobs were serviced

    Currently I'm having trouble how to establish that at this particular moment in time, if it equals the time the job should enter the server, go into the server if it's also the highest priority. I've tried creating other Queue<Job> queue1-3 to separate the priority of the jobs, but it seems to only print out one job if I do it that way(most likely an error on my part).

    I've tried adding above the if statements for priority if(time == thisJob.getTime()) {.......}, but it prints the 2nd job and only the 2nd job.
    file being input:
    200
    3
    1 1
    1 1
    1 1
    1 2
    1 2
    1 2
    1 3
    4 2
    10 1
    18 3
    18 3
    20 2
    22 1
    22 3
    51 1
    
    
    
    
    private static void runProj(String filename)
    {
        int time_job_has_been_in_server = 0;
        System.out.println("");
        System.out.println("Reading from file: "+filename);
            System.out.println("");
            try
            {
                BufferedReader br = new BufferedReader(new FileReader(filename));
                    Scanner scan = new Scanner(br);
                    
                int fileTime = scan.nextInt();
                int clock = scan.nextInt();
            jobServiced = 0;
            int duration = fileTime/2;
                queue = new Queue<Job>();
                server = new Queue<Job>();
                    
                System.out.println("Service time: "+clock);
                System.out.println("Duration: "+fileTime);
                System.out.println("");
    while(scan.hasNext())               //while there is a job needing to enter the system
    {
        int jobTime = scan.nextInt();
        int jobPriority = scan.nextInt();
        jobs = new Job(jobTime, jobPriority);
        queue.enqueue(jobs);
    }
                
    while(time <= duration && scan.hasNext() || !queue.isEmpty() || !server.isEmpty())
    {
        if(server.isEmpty())            //if the server is empty
        {
        if(!queue.isEmpty())        //if there is a job in queue && the server is empty
        {
           thisJob = queue.dequeue();
           if(thisJob.getPriority() == 1)
           {
              server.enqueue(thisJob);
              time_job_has_been_in_server = 0;
           }
          if(thisJob.getPriority() == 2)
          {
              server.enqueue(thisJob);
              time_job_has_been_in_server = 0;
          }
           if(thisJob.getPriority() == 3)
           {
            server.enqueue(thisJob);
            time_job_has_been_in_server = 0;
          }
            }
          }//end if
         else
          {
          time_job_has_been_in_server++;
          if(time_job_has_been_in_server == 3)    //has completed clock cycle
              {
              server.dequeue();                    //remove from server and increment jobServiced
              jobServiced++;
           }
           if(server.isEmpty())                    //if job in server is finished
           {
              System.out.println("Job # " + thisJob.getId() + " done @ time " + (time+2));
              time_job_has_been_in_server = 0;
          }
          }//end else
          time++;
         if(time >= (duration*2))
        throw new Exception ("Error: Infinite Loop");
    }//end while
    }//end runProj
    
    So far my output looks like this:
    Reading from file: test.dat

    Service time: 3
    Duration: 200

    Job # 1 done @ time 5
    Job # 2 done @ time 9
    Job # 3 done @ time 13
    Job # 4 done @ time 17
    Job # 5 done @ time 21
    Job # 6 done @ time 25
    Job # 7 done @ time 29
    Job # 8 done @ time 33
    Job # 9 done @ time 37
    Job # 10 done @ time 41
    Job # 11 done @ time 45
    Job # 12 done @ time 49
    Job # 13 done @ time 53
    Job # 14 done @ time 57
    Job # 15 done @ time 61

    Total jobs serviced: 15
    System halted @ time 61; all jobs were serviced

    I'm stuck and I can't rationalize how to solve this issue.

    I think in this situation having three queues is the way to go. I don't know why that was only printing one job, but try it again and see if you can't debug the problem.

    Look carefully at this block of code; what happens when it executes? I don't think it's what you meant to happen.
           thisJob = queue.dequeue();
           if(thisJob.getPriority() == 1)
           {
              server.enqueue(thisJob);
              time_job_has_been_in_server = 0;
           }
          if(thisJob.getPriority() == 2)
          {
              server.enqueue(thisJob);
              time_job_has_been_in_server = 0;
          }
           if(thisJob.getPriority() == 3)
           {
            server.enqueue(thisJob);
            time_job_has_been_in_server = 0;
          }
    
    Your timing bug is a result of your code not matching your description. Look at what happens on the third tick of a job being processed and compare it to what you said above.

    Smasher on
  • EvigilantEvigilant VARegistered User regular
    edited April 2009
    Smasher wrote: »
    I think in this situation having three queues is the way to go. I don't know why that was only printing one job, but try it again and see if you can't debug the problem.

    Look carefully at this block of code; what happens when it executes? I don't think it's what you meant to happen.
           thisJob = queue.dequeue();
           if(thisJob.getPriority() == 1)
           {
              server.enqueue(thisJob);
              time_job_has_been_in_server = 0;
           }
          if(thisJob.getPriority() == 2)
          {
              server.enqueue(thisJob);
              time_job_has_been_in_server = 0;
          }
           if(thisJob.getPriority() == 3)
           {
            server.enqueue(thisJob);
            time_job_has_been_in_server = 0;
          }
    
    Your timing bug is a result of your code not matching your description. Look at what happens on the third tick of a job being processed and compare it to what you said above.

    So I've tried the three queue thing without implementing time constraints when they enter the server.
    while(scan.hasNext())   			//while there is a job needing to enter the system
    {
    	int jobTime = scan.nextInt();
    	int jobPriority = scan.nextInt();
    	jobs = new Job(jobTime, jobPriority);
    	if(jobs.getPriority() == 1)
    	{
    		queue1.enqueue(jobs);
    	 }
    	 if(jobs.getPriority() == 2)
    	{
    		queue2.enqueue(jobs);
    	 }
    	else
    		queue3.enqueue(jobs);
    }
                
    while(time <= duration && scan.hasNext() || !queue1.isEmpty() || !queue2.isEmpty() || !queue3.isEmpty()  || !server.isEmpty())
    {
         if(server.isEmpty())			//if the server is empty
         {
    	if(!queue1.isEmpty())
    	{
    		thisJob = queue1.dequeue();
    		server.enqueue(thisJob);
    		time_job_has_been_in_server = 0;
    	}
    	if(queue1.isEmpty() && !queue2.isEmpty())
    	{
    		thisJob = queue2.dequeue();
    		server.enqueue(thisJob);
    		time_job_has_been_in_server = 0;
    	}
    	if(queue1.isEmpty() && queue2.isEmpty() && !queue3.isEmpty())
    	{
    		thisJob = queue3.dequeue();
    		server.enqueue(thisJob);
    		time_job_has_been_in_server = 0;
    	}
          }//end if
          else
          {
    		time_job_has_been_in_server++;
    		if(time_job_has_been_in_server == 3)	//has completed clock cycle
    	       {
    			server.dequeue();					//remove from server and increment jobServiced
    			jobServiced++;
    		}
    		if(server.isEmpty())					//if job in server is finished
    		{
    			System.out.println("Job # " + thisJob.getId() + " done @ time " + (time+2));
    			time_job_has_been_in_server = 0;
    		}
    	}//end else
    	time++;
    				
    	if(time > duration)
    	{
    		throw new Exception ("ERROR: Time Exceeded \n" + 
    						"Total jobs serviced: "+ jobServiced + "\n" +
    						"System halted @ time "+ (time+1) + "; not all jobs were serviced");
    	}
    

    1) I'm confused as hell how I should make sure that at x time pull x job with x priority from x queue
    2) In my command prompt, it prints this:

    job #1 done @ time 5
    job #2 done @ time 9
    job #3 done @ time 13
    job #9 done @ time 17
    job #13 done @ time 21
    java.lang.Exception: ERROR: Time Exceeded
    Total jobs serviced: 6
    System halted @ time 102; not all jobs were serviced

    Evigilant on
    XBL\PSN\Steam\Origin: Evigilant
  • JasconiusJasconius sword criminal mad onlineRegistered User regular
    edited April 2009
    Nightslyr wrote: »
    bowen wrote: »
    I don't know. It seems like you're vastly over-thinking this. Scope is one thing, but you're talking about communicating data between an event and a user or a class and another class.

    From what I've understood from the brief browse of your code and old posts.

    I probably am over-thinking it. I tend to do that. I just have it in my mind that I must have well-formed, professional code that takes into account the proper separation of application tiers and whatnot.

    The game is actually a giant learning exercise so I can learn proper OO techniques and how to build something the 'right' way. It probably won't go on my resume, but I'm trying to treat it as if it were.

    You're over thinking it and you made the mistake of not really pre-planning anything and just diving in. Suffice to say, based on what you've described (without looking directly at the source) you are not really painted into a corner. Such things like that are pretty rare. One thing you need to keep in mind is that you can write methods that have return types and not be forced to utilize them. If you want your method to return a string, that doesn't mean you have to use the string or even assign it to anything.

    That will probably solve one of those problems you mentioned.

    Jasconius on
  • SmasherSmasher Starting to get dizzy Registered User regular
    edited April 2009
    Evigilant wrote: »
    Smasher wrote: »
    I think in this situation having three queues is the way to go. I don't know why that was only printing one job, but try it again and see if you can't debug the problem.

    Look carefully at this block of code; what happens when it executes? I don't think it's what you meant to happen.
           thisJob = queue.dequeue();
           if(thisJob.getPriority() == 1)
           {
              server.enqueue(thisJob);
              time_job_has_been_in_server = 0;
           }
          if(thisJob.getPriority() == 2)
          {
              server.enqueue(thisJob);
              time_job_has_been_in_server = 0;
          }
           if(thisJob.getPriority() == 3)
           {
            server.enqueue(thisJob);
            time_job_has_been_in_server = 0;
          }
    
    Your timing bug is a result of your code not matching your description. Look at what happens on the third tick of a job being processed and compare it to what you said above.

    So I've tried the three queue thing without implementing time constraints when they enter the server.
    while(scan.hasNext())               //while there is a job needing to enter the system
    {
        int jobTime = scan.nextInt();
        int jobPriority = scan.nextInt();
        jobs = new Job(jobTime, jobPriority);
        if(jobs.getPriority() == 1)
        {
            queue1.enqueue(jobs);
         }
         if(jobs.getPriority() == 2)
        {
            queue2.enqueue(jobs);
         }
        else
            queue3.enqueue(jobs);
    }
                
    while(time <= duration && scan.hasNext() || !queue1.isEmpty() || !queue2.isEmpty() || !queue3.isEmpty()  || !server.isEmpty())
    {
         if(server.isEmpty())            //if the server is empty
         {
        if(!queue1.isEmpty())
        {
            thisJob = queue1.dequeue();
            server.enqueue(thisJob);
            time_job_has_been_in_server = 0;
        }
        if(queue1.isEmpty() && !queue2.isEmpty())
        {
            thisJob = queue2.dequeue();
            server.enqueue(thisJob);
            time_job_has_been_in_server = 0;
        }
        if(queue1.isEmpty() && queue2.isEmpty() && !queue3.isEmpty())
        {
            thisJob = queue3.dequeue();
            server.enqueue(thisJob);
            time_job_has_been_in_server = 0;
        }
          }//end if
          else
          {
            time_job_has_been_in_server++;
            if(time_job_has_been_in_server == 3)    //has completed clock cycle
               {
                server.dequeue();                    //remove from server and increment jobServiced
                jobServiced++;
            }
            if(server.isEmpty())                    //if job in server is finished
            {
                System.out.println("Job # " + thisJob.getId() + " done @ time " + (time+2));
                time_job_has_been_in_server = 0;
            }
        }//end else
        time++;
                    
        if(time > duration)
        {
            throw new Exception ("ERROR: Time Exceeded \n" + 
                            "Total jobs serviced: "+ jobServiced + "\n" +
                            "System halted @ time "+ (time+1) + "; not all jobs were serviced");
        }
    

    1) I'm confused as hell how I should make sure that at x time pull x job with x priority from x queue
    2) In my command prompt, it prints this:

    job #1 done @ time 5
    job #2 done @ time 9
    job #3 done @ time 13
    job #9 done @ time 17
    job #13 done @ time 21
    java.lang.Exception: ERROR: Time Exceeded
    Total jobs serviced: 6
    System halted @ time 102; not all jobs were serviced

    I don't think you have to worry too much about time. I'm assuming based on your example input file that the assignment assumes that all the jobs from the file are sorted by ascending time, so when you sort those into the three queues they should maintain that property within the separate queues. When you're getting the next job from the queue look at queue 1 first. If there's a job there and it's not too early to run the job then grab that one, otherwise move to queue 2, etc.

    Your error starts when you've drawn the last job out of queue 1. Your next conditional then checks if queue 1 is empty (which it is since you just removed the last element) and if there's something in queue 2. Since both of these are true it then gets a second job from the queue and puts it in the server.

    The next three clock cycles it works on the job, and then on the third cycle it dequeues the first job. Since there's still that second job in the server it doesn't print out the completion of the first job, and more importantly it doesn't reset the job timer. On every subsequent clock cycle the job timer will be greater than three, which means the second job will never be dequeued and will run until you hit the duration limit.

    Incidentally, you're still dividing the duration by two for some reason.

    Smasher on
  • ilmmadilmmad Registered User regular
    edited April 2009
    Antishow wrote: »
    Thanks! That's actually exactly what I was trying to accomplish! I was teaching an elementary school computer class and logo was a little over their heads, so Bill was born.

    That was a few years ago. I keep trying to make Bill2, but I'm caught in this cycle where I need to learn new techniques to make what I want, but then that expanded knowledge raises my personal standards, so then I need to learn MORE new techniques, and I end up never finishing anything.

    edit: Ugh, yeah I know. I'm so stupid. I lost the source a few years ago, so I can't fix it QQ

    Once while using StumbleUpon I came across a game that was the exact same as yours, with reskinning.

    I'm assuming you came first.

    ilmmad on
    Ilmmad.gif
  • EvigilantEvigilant VARegistered User regular
    edited April 2009
    Smasher wrote: »

    I don't think you have to worry too much about time. I'm assuming based on your example input file that the assignment assumes that all the jobs from the file are sorted by ascending time, so when you sort those into the three queues they should maintain that property within the separate queues. When you're getting the next job from the queue look at queue 1 first. If there's a job there and it's not too early to run the job then grab that one, otherwise move to queue 2, etc.

    Your error starts when you've drawn the last job out of queue 1. Your next conditional then checks if queue 1 is empty (which it is since you just removed the last element) and if there's something in queue 2. Since both of these are true it then gets a second job from the queue and puts it in the server.

    The next three clock cycles it works on the job, and then on the third cycle it dequeues the first job. Since there's still that second job in the server it doesn't print out the completion of the first job, and more importantly it doesn't reset the job timer. On every subsequent clock cycle the job timer will be greater than three, which means the second job will never be dequeued and will run until you hit the duration limit.

    Incidentally, you're still dividing the duration by two for some reason.

    Ah. So, I should have the server process the next job in it's queue and dequeue that? I'm trying to think on how I have it setup and how to correct it.

    Right now, as I understand it, this is what I believe is supposed to be happening:

    if the server is empty check
    if queue1 is not empty
    put a job into the server and make the time it's been in server 0
    else if queue 1 is empty and queue 2 is not empty
    put a job into the server and make the time it's been in server 0
    else if queue 1 and 2 are empty and queue 3 is not empty
    put a job into the server and make the time 0

    else if server is not empty
    means server has a job
    run 3 clock cycles to finish job
    dequeue job and increment jobs completed
    else if the server is empty
    means finished job
    print job # and when finished
    set time job has been in server to 0


    loop runs again
    grabs next job and repeats cycle

    I've changed the if statements that check the queue to else if to see if that would fix it some of my issues:
    if(server.isEmpty())			//if the server is empty
    {
    	if(!queue1.isEmpty())
    	{
    		thisJob = queue1.dequeue();
    		server.enqueue(thisJob);
    		time_job_has_been_in_server = 0;
    	}
    	else if(queue1.isEmpty() && !queue2.isEmpty())
    	{
    		thisJob = queue2.dequeue();
    		server.enqueue(thisJob);
    		time_job_has_been_in_server = 0;
    	}
    	else if(queue1.isEmpty() && queue2.isEmpty() && !queue3.isEmpty())
    	{
    		thisJob = queue3.dequeue();
    		server.enqueue(thisJob);
    		time_job_has_been_in_server = 0;
    	}
    

    This is my output:
    Reading from file: test.dat

    Service time: 3
    Duration: 200

    Job # 1 done @ time 5
    Job # 2 done @ time 9
    Job # 3 done @ time 13
    Job # 9 done @ time 17
    Job # 13 done @ time 21
    Job # 15 done @ time 25
    Job # 4 done @ time 29
    Job # 5 done @ time 33
    Job # 6 done @ time 37
    Job # 8 done @ time 41
    Job # 12 done @ time 45
    Job # 1 done @ time 49
    Job # 2 done @ time 53
    Job # 3 done @ time 57
    Job # 7 done @ time 61
    Job # 9 done @ time 65
    Job # 10 done @ time 69
    Job # 11 done @ time 73
    Job # 13 done @ time 77
    Job # 14 done @ time 81
    Job # 15 done @ time 85

    Total jobs serviced: 21
    System halted @ time 85; all jobs were serviced
    It's getting closer to what it should be.

    However:
    6 more jobs somehow ended up in the queue, and I have a feeling it's because of what you mentioned, that the server still has a job when another one is being pushed into it. I'll have to find a way of having the server work on that job before having another one pushed onto it.

    I have to implement a time statement to input each job at a specific time; right now while I'm seperating based on priority, they aren't going into the server at the time they're supposed to, which is screwing up my output.
    For example: Jobs 1-7 need to enter the system at time 1, but have different priorities 1-3. Job #8 needs to enter the system at time 4 and has a priority of 2. Job #9 needs to enter the system at time 10 with a priority of 1. Since job #9 has a higher priority than jobs #4-8, it will be the 4th job to finish and be printed out, followed by job #4, then job #5, then job #13, so on and so forth. As of right now, it goes great until after job #9 is printed. Then it starts printing out of order.

    As I understand it, since each job is clock cycles+2, I should divide the duration given to me in an example file(200), by 2 so that in actuality, there is 100 clock cycles.

    I'm so close to what it should be that it is extremely frustrating.

    Evigilant on
    XBL\PSN\Steam\Origin: Evigilant
  • redraptorredraptor Registered User regular
    edited April 2009
    I mentioned it in the general forum old Python thread but...

    Anyone doing pyweek? Signups are now.

    http://www.pyweek.org/

    redraptor on
  • KrisKris Registered User regular
    edited April 2009
    I really wish I had the time to participate in that.

    Kris on
  • SmasherSmasher Starting to get dizzy Registered User regular
    edited April 2009
    Evigilant wrote: »
    Smasher wrote: »

    I don't think you have to worry too much about time. I'm assuming based on your example input file that the assignment assumes that all the jobs from the file are sorted by ascending time, so when you sort those into the three queues they should maintain that property within the separate queues. When you're getting the next job from the queue look at queue 1 first. If there's a job there and it's not too early to run the job then grab that one, otherwise move to queue 2, etc.

    Your error starts when you've drawn the last job out of queue 1. Your next conditional then checks if queue 1 is empty (which it is since you just removed the last element) and if there's something in queue 2. Since both of these are true it then gets a second job from the queue and puts it in the server.

    The next three clock cycles it works on the job, and then on the third cycle it dequeues the first job. Since there's still that second job in the server it doesn't print out the completion of the first job, and more importantly it doesn't reset the job timer. On every subsequent clock cycle the job timer will be greater than three, which means the second job will never be dequeued and will run until you hit the duration limit.

    Incidentally, you're still dividing the duration by two for some reason.

    Ah. So, I should have the server process the next job in it's queue and dequeue that? I'm trying to think on how I have it setup and how to correct it.

    Right now, as I understand it, this is what I believe is supposed to be happening:

    if the server is empty check
    if queue1 is not empty
    put a job into the server and make the time it's been in server 0
    else if queue 1 is empty and queue 2 is not empty
    put a job into the server and make the time it's been in server 0
    else if queue 1 and 2 are empty and queue 3 is not empty
    put a job into the server and make the time 0

    else if server is not empty
    means server has a job
    run 3 clock cycles to finish job
    dequeue job and increment jobs completed
    else if the server is empty
    means finished job
    print job # and when finished
    set time job has been in server to 0


    loop runs again
    grabs next job and repeats cycle

    I've changed the if statements that check the queue to else if to see if that would fix it some of my issues:
    if(server.isEmpty())            //if the server is empty
    {
        if(!queue1.isEmpty())
        {
            thisJob = queue1.dequeue();
            server.enqueue(thisJob);
            time_job_has_been_in_server = 0;
        }
        else if(queue1.isEmpty() && !queue2.isEmpty())
        {
            thisJob = queue2.dequeue();
            server.enqueue(thisJob);
            time_job_has_been_in_server = 0;
        }
        else if(queue1.isEmpty() && queue2.isEmpty() && !queue3.isEmpty())
        {
            thisJob = queue3.dequeue();
            server.enqueue(thisJob);
            time_job_has_been_in_server = 0;
        }
    

    This is my output:
    Reading from file: test.dat

    Service time: 3
    Duration: 200

    Job # 1 done @ time 5
    Job # 2 done @ time 9
    Job # 3 done @ time 13
    Job # 9 done @ time 17
    Job # 13 done @ time 21
    Job # 15 done @ time 25
    Job # 4 done @ time 29
    Job # 5 done @ time 33
    Job # 6 done @ time 37
    Job # 8 done @ time 41
    Job # 12 done @ time 45
    Job # 1 done @ time 49
    Job # 2 done @ time 53
    Job # 3 done @ time 57
    Job # 7 done @ time 61
    Job # 9 done @ time 65
    Job # 10 done @ time 69
    Job # 11 done @ time 73
    Job # 13 done @ time 77
    Job # 14 done @ time 81
    Job # 15 done @ time 85

    Total jobs serviced: 21
    System halted @ time 85; all jobs were serviced
    It's getting closer to what it should be.

    However:
    6 more jobs somehow ended up in the queue, and I have a feeling it's because of what you mentioned, that the server still has a job when another one is being pushed into it. I'll have to find a way of having the server work on that job before having another one pushed onto it.

    I have to implement a time statement to input each job at a specific time; right now while I'm seperating based on priority, they aren't going into the server at the time they're supposed to, which is screwing up my output.
    For example: Jobs 1-7 need to enter the system at time 1, but have different priorities 1-3. Job #8 needs to enter the system at time 4 and has a priority of 2. Job #9 needs to enter the system at time 10 with a priority of 1. Since job #9 has a higher priority than jobs #4-8, it will be the 4th job to finish and be printed out, followed by job #4, then job #5, then job #13, so on and so forth. As of right now, it goes great until after job #9 is printed. Then it starts printing out of order.

    Currently all the jobs are being inserted into the queue in the beginning of the program. What I had in mind was that you'd check the time when you were looking through the queues for a new job, to make sure that it wasn't too early to begin working on that job. So, instead of just checking that queueX had a job in it, you'd check that it had a job and that the time of the first job in QueueX wasn't in the future. This wouldn't exactly simulate how the server would work, but the output would be identical.

    The alternative is to actually put the jobs into the appropriate queue when the corresponding clock tick arrive. If you do that you won't need to check the time when you draw from the queue (since anything in the queue can be run immediately), but you'll need a queue separate from the priority queues to hold jobs that haven't reached their time yet. You'll also need to examine that holding queue each clock cycle, and if necessary move one or more jobs in that queue into the appropriate priority queue.
    Evigilant wrote: »
    As I understand it, since each job is clock cycles+2, I should divide the duration given to me in an example file(200), by 2 so that in actuality, there is 100 clock cycles.

    Is the duration measured in jobs or clock cycles? If it's jobs then you should compare it directly to the number of jobs processed instead of the clock cycles. If it's clock cycles, then you're already keeping track of that in the time variable, so you can just compare that to the duration.

    Smasher on
  • EvigilantEvigilant VARegistered User regular
    edited April 2009
    Smasher wrote: »
    Currently all the jobs are being inserted into the queue in the beginning of the program. What I had in mind was that you'd check the time when you were looking through the queues for a new job, to make sure that it wasn't too early to begin working on that job. So, instead of just checking that queueX had a job in it, you'd check that it had a job and that the time of the first job in QueueX wasn't in the future. This wouldn't exactly simulate how the server would work, but the output would be identical.

    The alternative is to actually put the jobs into the appropriate queue when the corresponding clock tick arrive. If you do that you won't need to check the time when you draw from the queue (since anything in the queue can be run immediately), but you'll need a queue separate from the priority queues to hold jobs that haven't reached their time yet. You'll also need to examine that holding queue each clock cycle, and if necessary move one or more jobs in that queue into the appropriate priority queue.
    Evigilant wrote: »
    As I understand it, since each job is clock cycles+2, I should divide the duration given to me in an example file(200), by 2 so that in actuality, there is 100 clock cycles.

    Is the duration measured in jobs or clock cycles? If it's jobs then you should compare it directly to the number of jobs processed instead of the clock cycles. If it's clock cycles, then you're already keeping track of that in the time variable, so you can just compare that to the duration.

    This is where I get confused on how to sort it based on time and priority. I know how they are supposed to be sorted, but I'm stuck on creating code that does it.

    Do I do this while I'm creating the jobs and sticking them into the queues? For example:
    while(scan.hasNext())   			//while there is a job needing to enter the system
    {
    	int jobTime = scan.nextInt();
    	int jobPriority = scan.nextInt();
    	jobs = new Job(jobTime, jobPriority);
    	if(jobs.getTime() <=10)
           {
                    if(jobs.getPriority() == 1)
    	        {
    		       queue1.enqueue(jobs);
    	         }
    	         if(jobs.getPriority() == 2)
    	        {
    		       queue2.enqueue(jobs);
    	         }
    	         else
    		       queue3.enqueue(jobs);
            }
            else if(jobs.getTime() >=10 && <= 20)
           {
                    if(jobs.getPriority() == 1)
    	        {
    		       queue1.enqueue(jobs);
    	         }
    	         if(jobs.getPriority() == 2)
    	        {
    		       queue2.enqueue(jobs);
    	         }
    	         else
    		       queue3.enqueue(jobs);
            }
           else if(jobs.getTime() >=20 && <= 30)
           {
                    if(jobs.getPriority() == 1)
    	        {
    		       queue1.enqueue(jobs);
    	         }
    	         if(jobs.getPriority() == 2)
    	        {
    		       queue2.enqueue(jobs);
    	         }
    	         else
    		       queue3.enqueue(jobs);
            }
    }
    
    so on and so forth? Would that sort it out properly? If so, how could I shorten the code out rather than create increments in ten?

    Evigilant on
    XBL\PSN\Steam\Origin: Evigilant
This discussion has been closed.