Java | JavaScript | TypeScript | C++ | C# | Kotlin | Go Solution.
```Java []
public class Solution {

    private static final char EAST = 'E';
    private static final char WEST = 'W';
    private static final char SOUTH = 'S';
    private static final char NORTH = 'N';

    private int eastDistance = 0;
    private int westDistance = 0;
    private int southDistance = 0;
    private int northDistance = 0;

    public int maxDistance(String moves, int maxChange) {
        int maxDistance = 0;
        for (char move : moves.toCharArray()) {
            updateDistanceForDirection(move);
            maxDistance = Math.max(maxDistance, getDistanceWithoutChange() + getMaxIncreaseInDistance(maxChange));
        }
        return maxDistance;
    }

    private int getDistanceWithoutChange() {
        return Math.abs(eastDistance - westDistance) + Math.abs(southDistance - northDistance);
    }

    private int getMaxIncreaseInDistance(int maxChange) {
        int distanceIncrease = Math.min(eastDistance, westDistance) + Math.min(southDistance, northDistance);
        return 2 * Math.min(distanceIncrease, maxChange);
    }

    private void updateDistanceForDirection(char direction) {
        // 'Rule switch', applied here, does not need break statements.
        switch (direction) {
            case EAST ->
                ++eastDistance;
            case WEST ->
                ++westDistance;
            case SOUTH ->
                ++southDistance;
            case NORTH ->
                ++northDistance;
        }
    }
}
```
```JavaScript []
/**
 * @param {string} moves
 * @param {number} maxChange
 * @return {number}
 */
var maxDistance = function (moves, maxChange) {

    this.EAST = 'E';
    this.WEST = 'W';
    this.SOUTH = 'S';
    this.NORTH = 'N';

    this.eastDistance = 0;
    this.westDistance = 0;
    this.southDistance = 0;
    this.northDistance = 0;

    let maxDistance = 0;
    for (let move of moves) {
        updateDistanceForDirection(move);
        maxDistance = Math.max(maxDistance, getDistanceWithoutChange() + getMaxIncreaseInDistance(maxChange));
    }
    return maxDistance;
};

/**
 * @return {number}
 */
function getDistanceWithoutChange() {
    return Math.abs(this.eastDistance - this.westDistance) + Math.abs(this.southDistance - this.northDistance);
}

/**
 * @param {number} maxChange
 * @return {number}
 */
function getMaxIncreaseInDistance(maxChange) {
    const distanceIncrease = Math.min(this.eastDistance, this.westDistance) + Math.min(this.southDistance, this.northDistance);
    return 2 * Math.min(distanceIncrease, maxChange);
}

/**
 * @param {string} direction 
 * @return {void}
 */
function updateDistanceForDirection(direction) {
    switch (direction) {
        case this.EAST:
            ++this.eastDistance;
            break;
        case this.WEST:
            ++this.westDistance;
            break;
        case this.SOUTH :
            ++this.southDistance;
            break;
        case this.NORTH :
            ++this.northDistance;
    }
}
```
```TypeScript []
function maxDistance(moves: string, maxChange: number): number {

    this.EAST = 'E';
    this.WEST = 'W';
    this.SOUTH = 'S';
    this.NORTH = 'N';

    this.eastDistance = 0;
    this.westDistance = 0;
    this.southDistance = 0;
    this.northDistance = 0;

    let maxDistance = 0;
    for (let move of moves) {
        updateDistanceForDirection(move);
        maxDistance = Math.max(maxDistance, getDistanceWithoutChange() + getMaxIncreaseInDistance(maxChange));
    }
    return maxDistance;
};

function getDistanceWithoutChange(): number {
    return Math.abs(this.eastDistance - this.westDistance) + Math.abs(this.southDistance - this.northDistance);
}

function getMaxIncreaseInDistance(maxChange: number): number {
    const distanceIncrease = Math.min(this.eastDistance, this.westDistance) + Math.min(this.southDistance, this.northDistance);
    return 2 * Math.min(distanceIncrease, maxChange);
}

function updateDistanceForDirection(direction: string): void {
    switch (direction) {
        case this.EAST:
            ++this.eastDistance;
            break;
        case this.WEST:
            ++this.westDistance;
            break;
        case this.SOUTH:
            ++this.southDistance;
            break;
        case this.NORTH:
            ++this.northDistance;
    }
}
```
```C++ []
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

class Solution {

    static const char EAST = 'E';
    static const char WEST = 'W';
    static const char SOUTH = 'S';
    static const char NORTH = 'N';

    int eastDistance = 0;
    int westDistance = 0;
    int southDistance = 0;
    int northDistance = 0;

public:
    int maxDistance(const string& moves, int maxChange) {
        int maxDistance = 0;
        for (const auto& move : moves) {
            updateDistanceForDirection(move);
            maxDistance = max(maxDistance, getDistanceWithoutChange() + getMaxIncreaseInDistance(maxChange));
        }
        return maxDistance;
    }

private:
    int getDistanceWithoutChange() const {
        return abs(eastDistance - westDistance) + abs(southDistance - northDistance);
    }

    int getMaxIncreaseInDistance(int maxChange) const {
        int distanceIncrease = min(eastDistance, westDistance) + min(southDistance, northDistance);
        return 2 * min(distanceIncrease, maxChange);
    }   

    void updateDistanceForDirection(char direction) {
        switch (direction) {
            case EAST:
                ++eastDistance;
                break;
            case WEST:
                ++westDistance;
                break;
            case SOUTH:
                ++southDistance;
                break;
            case NORTH:
                ++northDistance;
        }
    }
};
```
```C# []
using System;

public class Solution
{
    private const char EAST = 'E';
    private const char WEST = 'W';
    private const char SOUTH = 'S';
    private const char NORTH = 'N';

    private int eastDistance = 0;
    private int westDistance = 0;
    private int southDistance = 0;
    private int northDistance = 0;

    public int MaxDistance(string moves, int maxChange)
    {
        int maxDistance = 0;
        foreach (char move in moves)
        {
            UpdateDistanceForDirection(move);
            maxDistance = Math.Max(maxDistance, GetDistanceWithoutChange() + GetMaxIncreaseInDistance(maxChange));
        }
        return maxDistance;
    }

    private int GetDistanceWithoutChange()
    {
        return Math.Abs(eastDistance - westDistance) + Math.Abs(southDistance - northDistance);
    }

    private int GetMaxIncreaseInDistance(int maxChange)
    {
        int distanceIncrease = Math.Min(eastDistance, westDistance) + Math.Min(southDistance, northDistance);
        return 2 * Math.Min(distanceIncrease, maxChange);
    }

    private void UpdateDistanceForDirection(char direction)
    {
        switch (direction)
        {
            case EAST:
                ++eastDistance;
                break;
            case WEST:
                ++westDistance;
                break;
            case SOUTH:
                ++southDistance;
                break;
            case NORTH:
                ++northDistance;
                break;
        }
    }
}
```
```Kotlin []
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min

class Solution {

    private companion object {
        const val EAST = 'E'
        const val WEST = 'W'
        const val SOUTH = 'S'
        const val NORTH = 'N'
    }

    private var eastDistance = 0
    private var westDistance = 0
    private var southDistance = 0
    private var northDistance = 0

    fun maxDistance(moves: String, maxChange: Int): Int {
        var maxDistance = 0
        for (move in moves) {
            updateDistanceForDirection(move)
            maxDistance = max(maxDistance, getDistanceWithoutChange() + getMaxIncreaseInDistance(maxChange))
        }
        return maxDistance
    }

    private fun getDistanceWithoutChange(): Int {
        return abs(eastDistance - westDistance) + abs(southDistance - northDistance)
    }

    private fun getMaxIncreaseInDistance(maxChange: Int): Int {
        val distanceIncrease = min(eastDistance, westDistance) + min(southDistance, northDistance)
        return 2 * min(distanceIncrease, maxChange)
    }

    private fun updateDistanceForDirection(direction: Char) {
        when (direction) {
            EAST -> ++eastDistance
            WEST -> ++westDistance
            SOUTH -> ++southDistance
            NORTH -> ++northDistance
        }
    }
}
```
```Go []
package main

import "math"

const EAST = 'E'
const WEST = 'W'
const SOUTH = 'S'
const NORTH = 'N'

var eastDistance int
var westDistance int
var southDistance int
var northDistance int

func maxDistance(moves string, maxChange int) int {
    eastDistance = 0
    westDistance = 0
    southDistance = 0
    northDistance = 0

    maxDistance := 0
    for _, move := range moves {
        updateDistanceForDirection(move)
        maxDistance = max(maxDistance, getDistanceWithoutChange()+getMaxIncreaseInDistance(maxChange))
    }
    return maxDistance
}

func getDistanceWithoutChange() int {
    return int(math.Abs(float64(eastDistance-westDistance)) + math.Abs(float64(southDistance-northDistance)))
}

func getMaxIncreaseInDistance(maxChange int) int {
    distanceIncrease := min(eastDistance, westDistance) + min(southDistance, northDistance)
    return 2 * min(distanceIncrease, maxChange)
}

func updateDistanceForDirection(direction rune) {
    switch direction {
    case EAST:
        eastDistance++
        break
    case WEST:
        westDistance++
        break
    case SOUTH:
        southDistance++
        break
    case NORTH:
        northDistance++
    }
}
```
['C++', 'Java', 'Go', 'TypeScript', 'Kotlin', 'JavaScript', 'C#']