Graalians

Graalians (https://www.graalians.com/forums/index.php)
-   Classic Future Improvements (https://www.graalians.com/forums/forumdisplay.php?f=26)
-   -   Perpetual Tournament Spar: Replace Present Tournament + Quick Spar Systems (https://www.graalians.com/forums/showthread.php?t=35114)

deadowl 04-05-2016 03:06 AM

Perpetual Tournament Spar: Replace Present Tournament + Quick Spar Systems
 
Was reading Thallen's post on changing the spar rooms in Supernick's. It seems like most of what he'd like to see is a better division of skill level.

I'll tell you what this solution accomplishes, then explain the details.
  1. It provides a natural division of skill level based on tiers.
  2. It can be scaled to eliminate the need for quick spar.

What this idea is based on is the 1v1 monthly spar tournaments of old, but rethinking it in a perpetualized manner.
  • Round One: eight rooms
  • Round Two: four rooms
  • Round Three: two rooms
  • Round Four: one room

In order for this to make sense, I'm going to need to relabel that.
  • Tier Four: eight rooms
  • Tier Three: four rooms
  • Tier Two: two rooms
  • Tier One: one room

So let's say there are only two players sparring at the time, they play in the Tier One.

Let's say there are three players sparring at the time. The first two players compete in the Tier One room. The remaining player is queued to face the winner.

Let's say there are four players sparring at the time. The winner of the Tier One room will face the winner of the Tier Two Room. The losers will face each other in the Tier Two room.

Let's say there are five players sparring at the time. The winner of the Tier One room will face the winner of the Tier Two Room. The loser of the Tier Two room will lose their spot in the queue to the fifth player. The loser of the Tier One room will face the fifth player.

Six Players? Use the Tier One room and both Tier Two rooms. The winners in each room will be added to the queue in the Tier One room. The losers of each room will face each other in the Tier Two rooms.

Seven Players? Same thing as with three players, but then the queue applies to the first slot available in Tier Two.

Eight Players? You suddenly have a Tier Three room to promote to a Tier Two room, and to demote a Tier Two loser to.
  • This algorithm naturally matches players against others of a similar skill level without assigning specific rooms based on an arbitrary measure of skill.
  • This algorithm can be implemented with an indefinite number of tiers, such that if there are a lot of people who want to spar, it can easily scale to meet the demand. This provides the scalability that can eliminate the need for "quick spar."

Marc 04-05-2016 05:12 AM

I like this idea, but I think what can be cool is have a auto run tourney room. Where 8 players join for lets say 100 gralats each, and the money gets seperated between the top 3. Kind of like 8 ball pool tournament system. Also get rid of the wins-loses.

and you gain rank points or lose depending on placement which would increase the difficulty of the tournament you enter in.

fp4 04-05-2016 05:28 AM

I've thought of implementing 'matchmaking' in the past but I fear the effect it might have on the social aspects of sparring.

Thallen 04-05-2016 05:36 AM

Quote:

Posted by fp4 (Post 692303)
I've thought of implementing 'matchmaking' in the past but I fear the effect it might have on the social aspects of sparring.

I think it would impact it heavily, but all of the socializing goes on in the lobby or in the streak room. I think very few would mind closing down the side rooms and replacing them with matchmaking!

Red 04-05-2016 05:38 AM

Quote:

Posted by Thallen (Post 692307)
I think it would impact it heavily, but all of the socializing goes on in the lobby or in the streak room. I think very few would mind closing down the side rooms and replacing them with matchmaking!

This - ivy

Aguzo 04-05-2016 06:47 AM

Quote:

Posted by fp4 (Post 692303)
I've thought of implementing 'matchmaking' in the past but I fear the effect it might have on the social aspects of sparring.

From side rooms, you would save yourself a lot of rage chat, unless they decide to pm you.

People can still socialize through pms, gc, and main lobby (the chair lines area).
Most of the time I am quiet in spar, don't really have time to talk, unless it's through pms.

Otherwise, I'm not following with "the social aspects of sparring". The spar rooms are mostly for spar. Obviously there are people who afk/chat with their friends, and watch matches, but the community can still socialize outside of the arena (Not the building).

Honestly though, I wouldn't mind not being able to watch matches, but you could just allow people to spectate current matches. Not sure what type of matchmaking system you are referring to, but if it's tier based, then you can have top sparrers matches at the top. Maybe like a replay? Clash Royale style.

Distorted_P2P 04-05-2016 06:48 AM

Quote:

Posted by fp4 (Post 692303)
I've thought of implementing 'matchmaking' in the past but I fear the effect it might have on the social aspects of sparring.

You could make viewing rooms?

Aguzo 04-05-2016 06:59 AM

Your tier rooms concept sounds pretty cool. Would be awesome for quick spar matches. What happens when someone decides to leave though? Does the highest player face the 2nd best or 3rd best? Do they have to wait, until the 2nd/3rd highest is finished with their match? or do they get paired against 4th/5th highest?

Also, if it's like this, then they should really get rid of losses, otherwise people might just spar, leave, and fight some nub to keep getting easy wins for that higher ratio.

Quote:

Posted by Distorted_P2P (Post 692321)
You could make viewing rooms?

Yeah, but he would either have to

1. make a lot of viewing rooms. Sounds like a pain to run around and watch matches. If there are matches going on than viewing rooms, then idk.

2. make it tier based, where top sparrers (if this is ranked), can be spectated, due to being at the top of the lists. Also prevents hackers from cheating.

or

3. Maybe add a favorite sparrer system, and that let's you watch other sparrers, so that it doesn't always have to be featured, and you can view your friends' matches.

I, personally prefer options 2 and 3. Not sure what other methods would be available. Would be cool if you could setup private matches, and invite others to spectate, without having to use the whole guild house scenario. Would also be awesome if in those private matches you could setup rules, such as first to # wins, sudden death (0.5), ice spar, etc.

Zetectic 04-05-2016 02:06 PM

Quote:

Posted by fp4 (Post 692303)
I've thought of implementing 'matchmaking' in the past but I fear the effect it might have on the social aspects of sparring.

Quote:

Posted by Thallen (Post 692307)
I think it would impact it heavily, but all of the socializing goes on in the lobby or in the streak room. I think very few would mind closing down the side rooms and replacing them with matchmaking!

^^these. let's not go so complicated.

deadowl 04-06-2016 01:42 AM

Quote:

Posted by Aguzo (Post 692322)
Your tier rooms concept sounds pretty cool. Would be awesome for quick spar matches. What happens when someone decides to leave though? Does the highest player face the 2nd best or 3rd best? Do they have to wait, until the 2nd/3rd highest is finished with their match? or do they get paired against 4th/5th highest?

You're perceptive. That's actually the hard part.

What I've got:

Let a roster be a list of players fighting in a tier in the order they'd be expected to spar (i.e. defender, challenger, second challenger, and so on).

Let the number of slots in a tier be the number of players that can fight in that tier at the same time (tier 1 has 2, tier 2 has 4, tier three has 8 and so on).

Calculate the relative bottom tier as either the highest tier with slots available, or the absolute bottom tier otherwise.

When promoting a player from one tier to another, promote them to at least the relative bottom tier. I.e. if there are any sparse tiers in-between, promote them to the relative bottom tier. This also works to assign a tier for a player entering without an assigned tier (i.e. put them at the bottom).

When demoting a player from one tier to another, if they're at or below the relative bottom tier, remove them from the tiering system (i.e. force them to rejoin).

Demotions and promotions always append to the end of the tier's roster, otherwise it would be much more difficult to interface with as a system.

Accommodate for removing a player altogether from the tiering system altogether (e.g. lag-outs, sign-offs, opt-outs).

I've just written a short script (js) that has those three things working. The only major issue is the automatic promotion of force-idled players that are tiered. Without automatic promotion, if there are only three sparrers, the third person always remains in queue for the second tier. That said, I'm trying to program something there that might cover when players leave and the "third person" is in a lower-tier queue without invoking an endless loop. I think I've got it though if anyone wants to test (see below, in HTML so you can just save it as HTML and then use the browser console to play around).

Quote:

Also, if it's like this, then they should really get rid of losses, otherwise people might just spar, leave, and fight some nub to keep getting easy wins for that higher ratio.
First, I don't see how that would be much different than the current quickspar system, aside from it would likely be much more diluted. Second, with actual tiers you can map spar stats to each tier, and that would at least out the losers who always lame on lower tiers (although I would consider that a bonus).


This isn't GScript. It provides functionality that would need to be translated and an interface built. I imagine a match being initiated for every two players in a roster as their position in the roster comes within the slot count. I imagine a win-loss mapping to promote-demote. I imagine a draw mapping to demote-demote. I imagine entering the queue mapping to promote. I imagine leaving the queue mapping to remove.

PHP Code:

<!DOCTYPE html>
<
html>
<
head>
<
title>Test</title>
<
meta charset="utf-8">
<
script>

class 
Tier {
    
constructor(index) {
        if (
index || !Number.isInteger(index)) throw new RangeError('Tier index must be a non-negative integer.');
        
this.index index;
        
this.level index 1;
        
this.slots << index 1;
        
this.roster = [];
    }
}

class 
TierManager {
    
constructor(tiers 4) { 
        
// establish participant map to look up tier and associated roster by participant
        
this.pMap = new Map();
        
// establish tiers
        
this.tiers = Array.from({lengthtiers}, (_i) => new Tier(i));
    }
    
getBottomTier() {
        
// determine the highest tier in which the roster size is less than the slots available
        
for (let i 0this.tiers.lengthi++) {
            if (
this.tiers[i].roster.length this.tiers[i].slots) {
                return 
this.tiers[i];
            }
        }
        
// otherwise the absolute bottom tier
        
return this.tiers[this.tiers.length 1];
    }
    
promote(p) {
        
let bottom this.getBottomTier();
        if (
this.pMap.has(p)) {
            
// determine source tier
            
let src this.tiers[this.pMap.get(p)]     ;
            
// only promote if the tier is not already the top
            
if (src.index 0) {
                
// update source roster
                
src.roster src.roster.filter(=> != p);
                
// promote to at least one tier above the relative bottom tier, at most the top tier, ideally up one tier
                
let refIndex Math.max(0Math.min(src.index 1bottom.index 1));
                
// determine destination tier
                
let dst this.tiers[refIndex];
                
// update destination roster
                
dst.roster.push(p);
                
// track tier reference in participant map
                
this.pMap.set(pdst.index);
            }
        } else {
            
// determine destination tier
            
let dst bottom;
            
// update roster
            
dst.roster.push(p);
            
// track tier reference in participant map
            
this.pMap.set(pdst.index);
        }
        
// promote idle participants
        
this.collapse();
    }
    
demote(p) {
        
// determine relative bottom tier (removing the player before would affect this)
        
let bottom this.getBottomTier()
        
// determine source tier
        
let src this.tiers[this.pMap.get(p)];
        
// update source roster
        
src.roster src.roster.filter(=> != p);
        
// promote idle participants
        
this.collapse();
        
// determine whether participant remains tiered
        
if (bottom.index src.index && bottom.roster.length 0) {
            
// determine destination tier
            
let dst this.tiers[src.index 1];
            
// update destination roster
            
dst.roster.push(p);
            
// track tier reference in participant map
            
this.pMap.set(pdst.index);
        } else {
            
// remove participant
            
this.remove(p);
        }
    }
    
remove(p) {
        
// determine source tier
        
let src this.tiers[this.pMap.get(p)];
        
// update source roster
        
src.roster src.roster.filter(=> != p);
        
// remove reference in participant map
        
this.pMap.delete(p);
        
// promote idle participants
        
this.collapse();
    }
    
collapse() {
        
// to establish a list of all idle participants
        
let idle = [];
        
// determine bottom tier (origin of promotion)
        
let bottom this.getBottomTier();
        for (
let i bottom.index 1this.tiers.lengthi++) {
            
// determine source tier
            
let src this.tiers[i];
            
// a participant is idle if the roster is larger than the number of slots
            
idle idle.concat(src.roster.slice(src.slots 1));
            
// a participant is idle if there are an odd number of roster spots
            
if (src.roster.length == 1) {
                
idle.push(src.roster[src.roster.length 1]);
            }
        }
        
// promote all idle players in order from top to bottom
        
for (let i 0idle.lengthi++) {
            
this.promote(idle[i]);
        }
    }
}
</script>
<body>
<h1>Hello!</h1> 


deadowl 04-07-2016 03:18 AM

Created a JS w/HTML testing version. This version is notable for being incomplete and untested code.

I believe that a player leaving should add their opponent to the front of the tier queue, although right now this code puts them at the end of the tier queue. I'm also not sure whether I like the auto-promotion behavior when there are other players on the tier.

This code is particularly untested compared to what I uploaded yesterday. If you save it as an HTML file and open it up in Firefox (it may or may not work in other browsers), you can play with it even if you don't know Javascript. The biggest caveat is that I haven't tested it very much. Another big caveat is that I didn't get around to styling yet, so it's not pretty to look at. I've got a lot of other things to do right now so nothing new will be happening tonight, and probably not tomorrow night either.

PHP Code:

<!DOCTYPE html>
<
html>
<
head>
<
title>Tiered Spar Manager Test</title>
<
meta charset="utf-8">
<
script>

class 
Tier {
    
constructor(index) {
        if (!
Number.isInteger(index) || index 0) {
            throw new 
RangeError('Tier index must be a non-negative integer.');
        }
        
this.index index;
        
this.level index 1;
        
this.slots Math.pow(2index 1);
        
this.roster = [];
    }
    
getLevel() {
        return 
this.level;
    }
    
// The total number of slots
    
getSlotCapacity() {
        return 
this.slots;
    }
    
// the
    
getMatchCapacity() {
        return 
this.slots 2;
    }
    
getSlotOccupancy() {
        return 
Math.min(this.slotsthis.roster.length);
    }
    
getMatchOccupancy() {
        return 
Math.floor(this.getSlotOccupancy() / 2);
    }
    
getSlotParticipant(offset) {
        if (!
Number.isInteger(offset) || offset || this.slots <= offset) {
            throw new 
RangeError(`Slot offset must be a non-negative integer less than ${this.slots}`);
        }
        return 
this.roster[offset];
    }
    
getMatchParticipants(offset) {
        
let participants;
        if (!
Number.isInteger(offset) || offset || this.slots <= offset) {
            throw new 
RangeError(`Match offset must be a non-negative integer less than ${this.slots 2}`);
        }
        if (
offset this.getMatchOccupancy()) { 
            
participants this.roster.slice(offsetoffset 2);
        }
        return 
participants;
    }
    
getMatchOpponent(p) {
        
let rosterIndex this.roster.indexOf(p);
        if (
rosterIndex 0) {
            throw new 
ReferenceError(`${p} not found among participants`);
        }
        
let queue this.getQueue();
        
let queueIndex queue.indexOf(p);
        if (
queueIndex >= 0) {
            throw new 
ReferenceError(`${p} is not in a match; p is in queue`);
        }
        
let opponent this.roster[rosterIndex + (rosterIndex == ? -1)];
        return 
opponent;
    }
    
getQueue() {
        
let queue = [];
        if (
this.roster.length >= this.slots) {
            
queue this.roster.slice(this.slots);
        } else if (
this.roster.length == 1) {
            
queue = [this.roster[this.roster.length 1]];
        }
        return 
queue;
    }
    
requeueParticipant(p) {
        
let rosterIndex this.roster.indexOf(p);
        if (
rosterIndex 0) {
            throw new 
ReferenceError(`${p} not found among participants`);
        }
        
this.roster.push(...this.roster.splice(rosterIndex1))
    }
}

class 
TierManager {
    
constructor(tiers 4) { 
        
// establish participant map to look up tier and associated roster by participant
        
this.pMap = new Map();
        
// establish tiers
        
this.tiers = Array.from({lengthtiers}, (_i) => new Tier(i));
    }
    
getTiers() {
        return 
this.tiers;
    }
    
getTierByLevel(level) {
        if (!
Number.isInteger(level) || level || this.tiers.length <= level) {
            throw new 
RangeError(`Tier level must be a non-negative integer greater than 0 and less than ${this.tiers.length}`);
        }
        return 
this.tiers[level 1]
    }
    
getTierByParticipant(p) {
        if (!
this.pMap.has(p)) {
            throw new 
ReferenceError(`${p} not found among participants`);
        }
        return 
this.tiers[this.pMap.get(p)];
    }
    
getBottomTier() {
        
// determine the highest tier in which the roster size is less than the slots available
        
for (let i 0this.tiers.lengthi++) {
            if (
this.tiers[i].roster.length this.tiers[i].slots) {
                return 
this.tiers[i];
            }
        }
        
// otherwise the absolute bottom tier
        
return this.tiers[this.tiers.length 1];
    }
    
promote(p) {
        
let bottom this.getBottomTier();
        if (
this.pMap.has(p)) {
            
// determine source tier
            
let src this.tiers[this.pMap.get(p)]     ;
            
// only promote if the tier is not already the top
            
if (src.index 0) {
                
// update source roster
                
src.roster src.roster.filter(=> != p);
                
// promote to at least one tier above the relative bottom tier, at most the top tier, ideally up one tier
                
let refIndex Math.max(0Math.min(src.index 1bottom.index 1));
                
// determine destination tier
                
let dst this.tiers[refIndex];
                
// update destination roster
                
dst.roster.push(p);
                
// track tier reference in participant map
                
this.pMap.set(pdst.index);
            }
        } else {
            
// determine destination tier
            
let dst bottom;
            
// update roster
            
dst.roster.push(p);
            
// track tier reference in participant map
            
this.pMap.set(pdst.index);
        }
        
// promote idle participants
        
this.collapse();
    }
    
demote(p) {
        
// determine relative bottom tier (removing the player before would affect this)
        
let bottom this.getBottomTier()
        
// determine source tier
        
let src this.tiers[this.pMap.get(p)];
        
// update source roster
        
src.roster src.roster.filter(=> != p);
        
// promote idle participants
        
this.collapse();
        
// determine whether participant remains tiered
        
if (bottom.index src.index && bottom.roster.length 0) {
            
// determine destination tier
            
let dst this.tiers[src.index 1];
            
// update destination roster
            
dst.roster.push(p);
            
// track tier reference in participant map
            
this.pMap.set(pdst.index);
        } else {
            
// remove participant
            
this.remove(p);
        }
    }
    
remove(p) {
        
// determine source tier
        
let src this.tiers[this.pMap.get(p)];
        
// update source roster
        
src.roster src.roster.filter(=> != p);
        
// remove reference in participant map
        
this.pMap.delete(p);
        
// promote idle participants
        
this.collapse();
    }
    
collapse() {
        
// to establish a list of all idle participants
        
let idle = [];
        
// determine bottom tier (origin of promotion)
        
let bottom this.getBottomTier();
        for (
let i bottom.index 1this.tiers.lengthi++) {
            
// determine source tier
            
let src this.tiers[i];
            
// a participant is idle if the roster is larger than the number of slots
            
idle idle.concat(src.roster.slice(src.slots 1));
            
// a participant is idle if there are an odd number of roster spots
            
if (src.roster.length == 1) {
                
idle.push(src.roster[src.roster.length 1]);
            }
        }
        
// promote all idle participants in order from top to bottom
        
for (let i 0idle.lengthi++) {
            
this.promote(idle[i]);
        }
    }
}
class 
TieredSparManager {
    
constructor(tiers 4) {
        
this.tm = new TierManager(tiers);
    }
    
addParticipant(p) {
        
this.tm.promote(p);
    }
    
removeParticipant(p) {
        
let tier this.tm.getTierByParticipant(p);
        try { 
            
let opponent tier.getMatchOpponent();
            
tier.requeueParticipant(opponent);
            
this.tm.remove(p);
        } catch (
e) {
            
this.tm.remove(p);
        }
    }
    
declareSparResult(p1p2cmp = -1) {
        
let p1Wins cmp 0;
        
let p2Wins cmp 0;
        
let draw cmp == 0;
        if (
p1Wins || draw) {
            
this.tm.demote(p2);
        } else {
            
this.tm.promote(p2);
        }
        if (
p2Wins || draw) {
            
this.tm.demote(p1);
        } else {
            
this.tm.promote(p1);
        }
    }
    
getTiers() {
        return 
this.tm.getTiers();
    }
    
toString() {
        return 
JSON.stringify(this.tm.getTiers());
    }
}

</script>
<body>
<h1>Tiered Sparring</h1>
<div>
    <form id="add-player">
        <fieldset>
            <legend>Join</legend>
            <input type="text" id="add-player-name" name="add-player-name" placeholder="Player Name">
            <button type="submit">Add Player</button>
        </fieldset>
    </form>
</div>
<script>
// display

let tsm = new TieredSparManager();
{
    let playerDivs = new Map();
    let pListener = event => {
        let formData = new FormData(event.target);
        if (formData.has('match-win')) {
            let winner = formData.get('match-win');
            let p1 = formData.get('match-p1');
            let p2 = formData.get('match-p2');
            let cmp = winner == p1 ? -1 : 1;
            tsm.declareSparResult(p1, p2, cmp);
            populateHTMLTiers();
        } else if (formData.has('match-draw') && formData.get('match-draw') == 'true') {
            let p1 = formData.get('match-p1');
            let p2 = formData.get('match-p2');
            tsm.declareSparResult(p1, p2, 0);
            populateHTMLTiers();
        } else if (formData.has('player-leave')) {
            tsm.removeParticipant(formData.get('player-leave'));
            populateHTMLTiers();
        }
        event.preventDefault();
        return false;
    };

    let createPlayerDiv = playerName => {
        let playerDiv = document.createElement('div');
        playerDiv.setAttribute('id', `p-${playerDivs.length}`);
        playerDiv.setAttribute('class', 'player');
        
        let playerH5 = document.createElement('h5');
        playerH5.textContent = playerName;
        playerDiv.appendChild(playerH5);
        
        let playerLeaveForm = document.createElement('form');
        playerLeaveForm.addEventListener('submit', pListener);
        
        let playerLeaveInput = document.createElement('input');
        playerLeaveInput.setAttribute('type', 'hidden');
        playerLeaveInput.setAttribute('name', 'player-leave');
        playerLeaveInput.setAttribute('value', playerName);
        playerLeaveForm.appendChild(playerLeaveInput);
        
        let playerLeaveButton = document.createElement('button');
        playerLeaveButton.setAttribute('type', 'submit');
        playerLeaveButton.textContent = `${playerName} Leaves`;
        playerLeaveForm.appendChild(playerLeaveButton);
        
        playerDiv.appendChild(playerLeaveForm);
        
        playerDivs.set(playerName, playerDiv);
        return playerDiv;
    };
    let createMatchDiv = (tier, matchIndex, p1Name, p2Name) => {
        let matchDiv = document.createElement('form');
        matchDiv.setAttribute('class','match');
        
        let matchH4 = document.createElement('h4');
        matchH4.textContent = `${p1Name} vs ${p2Name}`;
        matchDiv.appendChild(matchH4);
        
        let p1Div = playerDivs.get(p1Name);
        let p2Div = playerDivs.get(p2Name);
        matchDiv.appendChild(p1Div);
        matchDiv.appendChild(p2Div);

        let p1Input = document.createElement('input');
        p1Input.setAttribute('type', 'hidden');
        p1Input.setAttribute('name', 'match-p1');
        p1Input.setAttribute('value', p1Name);
        matchDiv.appendChild(p1Input);

        let p2Input = document.createElement('input');
        p2Input.setAttribute('type', 'hidden');
        p2Input.setAttribute('name', 'match-p2');
        p2Input.setAttribute('value', p2Name);
        matchDiv.appendChild(p2Input);
        
        let p1WinInput = document.createElement('input');
        p1WinInput.setAttribute('type', 'hidden');
        p1WinInput.setAttribute('name', 'match-win');
        p1WinInput.setAttribute('value', p1Name);
        
        let p2WinInput = document.createElement('input');
        p2WinInput.setAttribute('type', 'hidden');
        p2WinInput.setAttribute('name', 'match-win');
        p2WinInput.setAttribute('value', p2Name);

        let matchDrawInput = document.createElement('input');
        matchDrawInput.setAttribute('type', 'hidden');
        matchDrawInput.setAttribute('name', 'match-draw');
        matchDrawInput.setAttribute('value', 'true');

        let p1MatchWinButton = document.createElement('button');
        p1MatchWinButton.setAttribute('type', 'submit');
        p1MatchWinButton.textContent = `${p1Name} Wins`;

        let p2MatchWinButton = document.createElement('button');
        p2MatchWinButton.setAttribute('type', 'submit');
        p2MatchWinButton.textContent = `${p2Name} Wins`;

        let matchDrawButton = document.createElement('button');
        matchDrawButton.setAttribute('type', 'submit');
        matchDrawButton.textContent = `Draw`;
        
        let p1MatchWinForm = document.createElement('form');
        p1MatchWinForm.appendChild(p1Input.cloneNode());
        p1MatchWinForm.appendChild(p2Input.cloneNode());
        p1MatchWinForm.appendChild(p1WinInput);
        p1MatchWinForm.appendChild(p1MatchWinButton);
        p1MatchWinForm.addEventListener('submit', pListener);
        matchDiv.appendChild(p1MatchWinForm);
        
        let p2MatchWinForm = document.createElement('form');
        p2MatchWinForm.appendChild(p1Input.cloneNode());
        p2MatchWinForm.appendChild(p2Input.cloneNode());
        p2MatchWinForm.appendChild(p2WinInput);
        p2MatchWinForm.appendChild(p2MatchWinButton);
        p2MatchWinForm.addEventListener('submit', pListener);
        matchDiv.appendChild(p2MatchWinForm);
                
        let matchDrawForm = document.createElement('form');
        matchDrawForm.appendChild(p1Input.cloneNode());
        matchDrawForm.appendChild(p2Input.cloneNode());
        matchDrawForm.appendChild(matchDrawInput);
        matchDrawForm.appendChild(matchDrawButton);
        matchDrawForm.addEventListener('submit', pListener);
        matchDiv.appendChild(matchDrawForm);
        
        return matchDiv;
    };
    let createQueueForm = (tier, players) => {
        let queueForm = document.createElement('form');
        queueForm.setAttribute('class', 'queue');
        players.forEach(player => { queueForm.appendChild(playerDivs.get(player)); });
        queueForm.addEventListener('submit', pListener);
        return queueForm;
    }
    let populateHTMLTiers = () => {
        let matchDivs = document.getElementsByClassName('match');
        Array.from(matchDivs).forEach(matchDiv => matchDiv.remove());
        let queueForms = document.getElementsByClassName('queue');
        Array.from(queueForms).forEach(queueForm => queueForm.remove());
        let tiers = tsm.getTiers();
        tiers.forEach(function (tier) {
            for (let i = 0; i < tier.getMatchOccupancy(); i++) {
                let [p1, p2] = tier.getMatchParticipants(i);
                let matchDiv = createMatchDiv(tier, i, p1, p2);
                let parentId = `t${tier.level}m${i}`;
                let parent = document.getElementById(parentId);
                parent.appendChild(matchDiv);
            }
            let queueForm = createQueueForm(tier, tier.getQueue());                
            let parentId= `t${tier.level}q`;
            let parent = document.getElementById(parentId);
            parent.appendChild(queueForm);

        });
    };
    let body = document.getElementsByTagName('body')[0];
    let tiers = tsm.getTiers();
    tiers.forEach(tier => {
        let tierDiv = document.createElement('div');
        tierDiv.setAttribute('id', `t${tier.level}`);
        
        let tierH2 = document.createElement('h2');
        tierH2.textContent = `Tier ${tier.getLevel()}`;
        tierDiv.appendChild(tierH2);
        
        let matchCapacity = tier.getMatchCapacity();
        for (let i = 0; i < matchCapacity; i++) {
            let matchDiv = document.createElement('div');
            matchDiv.setAttribute('id', `t${tier.level}m${i}`);
            
            let matchH3 = document.createElement('h3');
            matchH3.textContent = `Room ${i + 1}`;
            matchDiv.appendChild(matchH3);
            
            tierDiv.appendChild(matchDiv);
        }
        
        let queueDiv = document.createElement('div');
        queueDiv.setAttribute('id', `t${tier.level}q`);
        
        let queueH3 = document.createElement('h3');
        queueH3.textContent = 'Queue';
        queueDiv.appendChild(queueH3);
        
        tierDiv.appendChild(queueDiv);
        body.appendChild(tierDiv);
    });
    addPlayerForm = document.getElementById('add-player');
    addPlayerForm.addEventListener('submit', function (event) {
        let playerName = document.getElementById('add-player-name').value;
        if (playerName.length == 0) {
            event.preventDefault();
            return false;
        }
        createPlayerDiv(playerName);
        tsm.addParticipant(playerName);
        populateHTMLTiers();
        event.preventDefault();        
        return false;
    });
}
</script> 


Crono 04-07-2016 09:27 AM

javascript...html...are you a front-end dev??

deadowl 04-07-2016 02:17 PM

Quote:

Posted by Crono (Post 692989)
javascript...html...are you a front-end dev??

Would you prefer Python/MIME/SMTP?

Crono 04-07-2016 05:51 PM

Quote:

Posted by deadowl (Post 693022)
Would you prefer Python/MIME/SMTP?

nah i operate on dank/FKN/memes

Zetectic 04-08-2016 12:47 AM

Quote:

Posted by Crono (Post 693064)
nah i operate on dank/FKN/memes

lmfaoo

btw why isn't classic hiring any dev? i saw a thread made by NaS in 2014- he's a reputable coder, but u guys never hired him, but y'all always seems like hands are full, so why not get a new volunteer? *cough*deadowl*cough* idk, he seems like he has some experience and willing to help out classic. js.


All times are GMT. The time now is 01:38 PM.

Powered by vBulletin/Copyright ©2000 - 2026, vBulletin Solutions Inc.